# Agent instructions
Follow `.github/copilot-instructions.md` for repository-specific development guidance.
## Issues
Before filing a GitHub issue in this repository:
1. Search existing open and closed issues for duplicates.
2. Use the GitHub issue forms in `.github/ISSUE_TEMPLATE/`; do not file a blank issue unless a maintainer explicitly asks for one.
3. For bugs, include the same information requested by the Bug Report form: relevant area, command if applicable, brief description, steps to reproduce, expected behavior, actual behavior, and environment.
4. For feature requests, include the same information requested by the Feature Request form: relevant area, description of the new feature or enhancement, and proposed technical implementation details when known.
5. Keep issue bodies concise and evidence-based. Do not paste large speculative patches into issue bodies; open a pull request or link a branch when code is available.
## Pull requests
Before opening a pull request:
1. Review `CONTRIBUTING.md` and follow the repository PR template.
2. Keep each PR focused on one logical change.
3. Include or update tests and documentation when the change affects behavior, command output, user guidance, or public APIs.
4. Summarize validation performed, or explain why validation was not run.
# WinGet CLI Development Guide
## Project Overview
This is the Windows Package Manager (WinGet) CLI client - a native Windows application for discovering and installing packages. The codebase consists of:
- **C++/WinRT client** (`src/AppInstallerCLI*`) - The main CLI and core logic
- **COM API** (`src/Microsoft.Management.Deployment`) - Public Windows Runtime API for programmatic access
- **PowerShell modules** (`src/PowerShell`) - Microsoft.WinGet.Client and Microsoft.WinGet.Configuration cmdlets
- **Configuration system** - DSC-based system configuration using WinGet
## Building, Testing, and Running
### Initial Setup
Use a configuration file in `.config` as in `winget configure .config/configuration.winget` (alternatives provided for other VS SKUs).
Manual steps:
1. Install Visual Studio 2022 with required workloads (see `.vsconfig`)
2. Install Windows SDK 10.0.26100: `winget install Microsoft.WindowsSDK.10.0.26100`
3. Enable developer mode in Windows
4. Run `vcpkg integrate install` from Developer Command Prompt
### Building
Open `src\AppInstallerCLI.sln` in Visual Studio and build the solution (Ctrl+Shift+B) or use msbuild.exe to build from the command line.
The solution uses:
- MSBuild
- vcpkg for C++ dependencies
- NuGet for C++ and .NET dependencies
### Running/Debugging
1. Deploy solution: Build > Deploy Solution
2. Run from command line: `wingetdev`
3. For debugging:
- Right-click `AppInstallerCLIPackage` > Properties > Debug tab
- Set Debugger type to "Native Only" for both Application and Background task processes
- Select "Do not launch, but debug my code when it starts"
- Press F5 and run `wingetdev` in a separate terminal
Entry point: `src/AppInstallerCLI/main.cpp`
### Testing
#### C++ Unit Tests (Catch2)
Located in `AppInstallerCLITests` project. After building:
```powershell
# Run all tests
src\<ARCH>\<Debug|Release>\AppInstallerCLITests\AppInstallerCLITests.exe
# Run specific test
src\<ARCH>\<Debug|Release>\AppInstallerCLITests\AppInstallerCLITests.exe TestName
# Available options
AppInstallerCLITests.exe --help
```
#### .NET Tests
- `Microsoft.WinGet.UnitTests` - PowerShell module tests
- `Microsoft.Management.Configuration.UnitTests` - Configuration system tests
- `WinGetUtilInterop.UnitTests` - Interop layer tests
#### E2E Tests
`AppInstallerCLIE2ETests` project contains end-to-end integration tests.
## Architecture
### Core Components
**AppInstallerCLICore** - Core CLI logic organized around:
- **ExecutionContext**: State container that flows through workflows. Contains arguments, reporter, flags, and data (ExecutionContextData.h)
- **Workflows**: Composable functions that take ExecutionContext and perform operations (e.g., InstallFlow, UpdateFlow, SearchFlow)
- **Commands**: Parse arguments and orchestrate workflows
- **Reporter**: Handles all user output (ExecutionReporter.h)
**AppInstallerRepositoryCore** - Package source abstraction:
- Interfaces for different source types (REST, SQLite index, Microsoft Store, composite)
- Search, match, and correlation logic
- Package version selection and dependencies
**AppInstallerCommonCore** - Shared utilities:
- Manifest parsing (YAML/JSON)
- Settings and group policy
- Telemetry and logging
- HTTP client, downloader, archive handling
**Microsoft.Management.Deployment** - COM API surface:
- IDL definitions in `PackageManager.idl`
- WinRT projections for external consumption
- Used by PowerShell modules and third-party integrations
**AppInstallerCLIPackage** - Dev MSIX package definition:
- Models the release package definition as closely as possible.
- Contains localized string resources at src\AppInstallerCLIPackage\Shared\Strings\en-us\winget.resw
### Key Patterns
**Workflow Pattern**: Functions that operate on ExecutionContext:
```cpp
void WorkflowTask(Execution::Context& context)
{
// Check if already terminated
AICLI_RETURN_IF_TERMINATED(context);
// Access data
auto& data = context.Get<Data::Installer>();
// Report to user
context.Reporter.Info() << "Doing something";
// Store data for next workflow
context.Add<Data::SomeResult>(result);
// Terminate on error
if (failed)
{
AICLI_TERMINATE_CONTEXT(HRESULT);
}
}
```
**Source Composition**: Multiple package sources can be composed:
- CompositeSource combines multiple sources with conflict resolution
- Installed source tracks locally installed packages
- Available sources provide packages to install
**Manifest Schema**: Package manifests use versioned YAML schemas:
- Schema definitions in `schemas/JSON/manifests/`
- Parsing in `AppInstallerCommonCore/Manifest/`
- Multi-file manifests: installer, locale, version, defaultLocale
## Naming Conventions
- **Namespace structure**: `AppInstaller::<Area>[::<Subarea>]`
- `AppInstaller::CLI::Execution` - CLI execution context
- `AppInstaller::CLI::Workflow` - Workflow functions
- `AppInstaller::Repository` - Repository/source logic
- `AppInstaller::Manifest` - Manifest types
- `AppInstaller::Settings` - User/admin settings
- **Macros**: Prefixed with `AICLI_` for CLI, `WINGET_` for general
- **Data keys**: ExecutionContextData uses enum keys to type-safely store/retrieve data
## Windows-Specific Considerations
- Use Windows-style paths with backslashes (`\`)
- Leverage WinRT APIs via C++/WinRT projections
- COM threading models matter - client uses multi-threaded apartment (MTA)
- Package deployment uses Windows App SDK / MSIX infrastructure
- Requires Windows 10 1809+ (build 17763)
## Contributing
- Review `CONTRIBUTING.md` for workflow
- File/discuss issues before starting work
- Specs required for features (stored in `doc/specs/`); see `.github/instructions/specs.instructions.md` for detailed guidance
- Follow existing code style (see `stylecop.json`)
- CI runs on Azure Pipelines (`azure-pipelines.yml`)
## Issues and Pull Requests
- Before filing an issue, search existing open and closed issues for duplicates.
- Use the GitHub issue forms in `.github/ISSUE_TEMPLATE/`; do not file a blank issue unless a maintainer explicitly asks for one.
- Bug reports should include the form fields for relevant area, command if applicable, brief description, steps to reproduce, expected behavior, actual behavior, and environment.
- Feature requests should include the form fields for relevant area, feature or enhancement description, and proposed technical implementation details when known.
- Keep issue bodies concise and evidence-based. Do not paste large speculative patches into issue bodies; open a pull request or link a branch when code is available.
- Before opening a pull request, review `CONTRIBUTING.md`, follow the PR template, keep the change focused, and summarize validation performed.
## Useful Commands
```powershell
# Get WinGet client info
wingetdev --info
# Show experimental features
wingetdev features
# Check sources
wingetdev source list
```
## Localization
### Source of truth
The English resource file `src\AppInstallerCLIPackage\Shared\Strings\en-us\winget.resw` is the only file contributors should edit for string changes. It feeds the Microsoft localization pipeline.
The files under `Localization\Resources\<locale>\` are **automatically synced from Microsoft's internal localization system and must not be edited**. Any manual edits will be overwritten on the next sync.
Every string that could be misunderstood without context should have a `<comment>`.
### Triggering retranslation
- **Changing a string's `<value>`** automatically queues it for retranslation on the next localization sync.
- **Changing only a `<comment>`** does NOT trigger retranslation. Comments improve future translations but do not fix existing ones.
To fix an existing bad translation, a bug has to be filed internally with the localization team.