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
116 changes: 16 additions & 100 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,139 +1,55 @@
root = true

[*.cs]
# Formatting
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = crlf
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

# New lines
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true

# Indentation
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left

# Spacing
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_after_comma = true
csharp_space_before_comma = false

# Line preservation
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true

# Naming Symbols
# Naming symbols
dotnet_naming_symbols.public_properties.applicable_kinds = property
dotnet_naming_symbols.public_properties.applicable_accessibilities = public

dotnet_naming_symbols.public_fields.applicable_kinds = field
dotnet_naming_symbols.public_fields.applicable_accessibilities = public

dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private

dotnet_naming_symbols.private_methods.applicable_kinds = method
dotnet_naming_symbols.private_methods.applicable_accessibilities = private

dotnet_naming_symbols.constants.applicable_kinds = field
dotnet_naming_symbols.constants.required_modifiers = const

dotnet_naming_symbols.local_variables.applicable_kinds = local
dotnet_naming_symbols.local_variables.applicable_accessibilities = local

dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.parameters.applicable_accessibilities = *

# Naming Styles
# Naming styles
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.camel_case_underscore.required_prefix = _
dotnet_naming_style.camel_case_underscore.capitalization = camel_case

dotnet_naming_style.camel_case.capitalization = camel_case

dotnet_naming_style.constant_style.capitalization = pascal_case

# Naming Rules
# Naming rules (warning: visible in CLI builds, not just the IDE)
dotnet_naming_rule.public_props_must_be_pascal.symbols = public_properties
dotnet_naming_rule.public_props_must_be_pascal.style = pascal_case
dotnet_naming_rule.public_props_must_be_pascal.severity = suggestion

dotnet_naming_rule.public_props_must_be_pascal.severity = warning
dotnet_naming_rule.public_fields_must_be_pascal.symbols = public_fields
dotnet_naming_rule.public_fields_must_be_pascal.style = pascal_case
dotnet_naming_rule.public_fields_must_be_pascal.severity = suggestion

dotnet_naming_rule.public_fields_must_be_pascal.severity = warning
dotnet_naming_rule.private_fields_must_be_camel.symbols = private_fields
dotnet_naming_rule.private_fields_must_be_camel.style = camel_case_underscore
dotnet_naming_rule.private_fields_must_be_camel.severity = suggestion

dotnet_naming_rule.private_fields_must_be_camel.severity = warning
dotnet_naming_rule.private_methods_must_be_pascal.symbols = private_methods
dotnet_naming_rule.private_methods_must_be_pascal.style = pascal_case
dotnet_naming_rule.private_methods_must_be_pascal.severity = suggestion

dotnet_naming_rule.constants_must_be_pascal_with_prefix.symbols = constants
dotnet_naming_rule.constants_must_be_pascal_with_prefix.style = constant_style
dotnet_naming_rule.constants_must_be_pascal_with_prefix.severity = suggestion

dotnet_naming_rule.private_methods_must_be_pascal.severity = warning
dotnet_naming_rule.constants_must_be_pascal.symbols = constants
dotnet_naming_rule.constants_must_be_pascal.style = pascal_case
dotnet_naming_rule.constants_must_be_pascal.severity = warning
dotnet_naming_rule.locals_must_be_camel.symbols = local_variables
dotnet_naming_rule.locals_must_be_camel.style = camel_case
dotnet_naming_rule.locals_must_be_camel.severity = suggestion

dotnet_naming_rule.locals_must_be_camel.severity = warning
dotnet_naming_rule.parameters_must_be_camel.symbols = parameters
dotnet_naming_rule.parameters_must_be_camel.style = camel_case
dotnet_naming_rule.parameters_must_be_camel.severity = suggestion

# var preferences
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion

# Expression-bodied members
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_operators = when_on_single_line:suggestion
csharp_style_expression_bodied_properties = when_on_single_line:suggestion
csharp_style_expression_bodied_indexers = when_on_single_line:suggestion
csharp_style_expression_bodied_accessors = when_on_single_line:suggestion
csharp_style_expression_bodied_lambdas = when_on_single_line:suggestion
csharp_style_expression_bodied_local_functions = when_on_single_line:suggestion
# csharp_style_expression_bodied_methods = when_on_single_line:suggestion

# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion

# Null checking preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
dotnet_naming_rule.parameters_must_be_camel.severity = warning

# Other preferences
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_prefer_static_local_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
# CSharpier owns whitespace and layout
dotnet_diagnostic.IDE0055.severity = none
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns: ["*"]
- package-ecosystem: nuget
directory: /
schedule:
interval: weekly
ignore:
# Date-versioned and tied to the PowerToys target; see CLAUDE.md (bump-deps skill)
- dependency-name: Microsoft.CommandPalette.Extensions
- dependency-name: Microsoft.WindowsAppSDK
- dependency-name: Microsoft.Windows.CsWinRT
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build-test:
runs-on: windows-2022
timeout-minutes: 30

steps:
# .editorconfig requires CRLF for .cs; match a Windows checkout so csharpier passes
- name: Use CRLF checkout
run: git config --global core.autocrlf true

- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
fetch-depth: 0
fetch-tags: true

- name: Setup .NET SDK
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: 10.0.x
cache: true
cache-dependency-path: |
**/Directory.Packages.props
**/*.csproj

- name: Restore tools
run: dotnet tool restore

- name: Check formatting
run: dotnet tool run csharpier check .

- name: Build (Release, x64)
run: dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false

# The unpackaged exe auto-initializes the Windows App SDK bootstrapper, which hangs the
# test host on runners without the Windows App Runtime; tests only need ProjectParser.
- name: Test
timeout-minutes: 10
run: dotnet test UnityExtension.Tests/UnityExtension.Tests.csproj -c Release -p:Platform=x64 -p:WindowsAppSdkBootstrapInitialize=false --blame-hang --blame-hang-timeout 2m

validate-version:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Check csproj and manifest versions agree
run: |
v=$(grep -oP '(?<=<Version>)[^<]+' UnityExtension/UnityExtension.csproj | head -1)
a=$(grep -oP '(?<=<AssemblyVersion>)[^<]+' UnityExtension/UnityExtension.csproj | head -1)
f=$(grep -oP '(?<=<FileVersion>)[^<]+' UnityExtension/UnityExtension.csproj | head -1)
m=$(grep -oP '<Identity[^>]*\sVersion="\K[^"]+' UnityExtension/Package.appxmanifest | head -1)
echo "csproj=$v assembly=$a file=$f manifest=$m"
test "$a" = "$v.0" && test "$f" = "$v.0" && test "$m" = "$v.0"
9 changes: 5 additions & 4 deletions .github/workflows/release-msix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ concurrency:
jobs:
build-sign-release:
runs-on: windows-2022
timeout-minutes: 45

defaults:
run:
Expand All @@ -27,21 +28,21 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
fetch-depth: 0
fetch-tags: true

- name: Cache NuGet packages
uses: actions/cache@v4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/Directory.Packages.props', '**/Directory.Build.props', '**/*.csproj', '**/nuget.config') }}
restore-keys: |
${{ runner.os }}-nuget-

- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

Expand Down Expand Up @@ -186,7 +187,7 @@ jobs:
}

- name: Upload workflow artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: signed-msix
path: |
Expand Down
12 changes: 5 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Store identity: `YidiMao.CommandPalette-Unity` (private values in git-ignored `d
- `Directory.Packages.props` = all package versions; `dotnet-tools.json` = csharpier, minver-cli; `.pre-commit-config.yaml` = hooks
- No Markdown under `UnityExtension/`; contributor guidance -> `CONTRIBUTING.md`; user docs -> `docs/`
- Local-only (git-ignored, do not commit): `.claude/settings.local.json`, `docs/store-identity.md`, `scripts/` (`sign.ps1`, `pfx.ps1`, Unity path helpers)
- No test project exists; verify manually in PowerToys
- `UnityExtension.Tests/` (xunit) covers `ProjectParser` only; verify UI and commands manually in PowerToys
- Gallery metadata lives in `microsoft/CmdPal-Extensions` (`extensions/maoyeedy/cmdpal-unity-extension/`), not in this repo

## Docs and tooling (use before answering from memory)
Expand Down Expand Up @@ -47,19 +47,17 @@ dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64
dotnet build UnityExtension/UnityExtension.csproj -c Release -p:Platform=x64 -p:SuppressSdkNoise=false # trim/AOT review
```

- Debug CLI build is green (0 warnings, 0 errors) as of this refresh
- CLI `Register` deploys need `-p:WindowsPackageType=MSIX`; MSIX bundle builds need `-p:GenerateAppxPackageOnBuild=true` (see `deploy` skill)
- `IL2081` / `IL2104` from CsWinRT projections are known and non-fatal
- After rebuild, reload Command Palette or restart PowerToys; test in the real host
- Build fails with MSB3021/MSB3027 "locked by: Unity Extension for Command Palette" = extension is running, not a code error. Compile-check with `-p:OutDir=<other dir>/` and never kill it (see `docs/TROUBLESHOOTING.md`)

## Gotchas

- `ProjectParser` swallows exceptions and may silently return an empty list
- Extension not loading: check manifest registration and CLSID first
- Breakpoints not hit: attach VS to the extension process, not the host shell
- `Microsoft.CommandPalette.Extensions` is date-versioned (currently 0.9.260303001); bump only for a newer PowerToys target
- `Microsoft.WindowsAppSDK` (2.2.0, matches PowerToys) and `Microsoft.Windows.CsWinRT` (2.2.0) must stay mutually compatible; keep <= PowerToys' pins
- Version sync: `Package.appxmanifest` Identity Version <-> `.csproj` `<Version>`/`<AssemblyVersion>`/`<FileVersion>` (currently 0.1.3 / 0.1.3.0); 4th segment `.0`. CI fails the tag build on mismatch
- `Microsoft.CommandPalette.Extensions` is date-versioned; bump only for a newer PowerToys target
- `Microsoft.WindowsAppSDK` and `Microsoft.Windows.CsWinRT` must stay mutually compatible; keep <= PowerToys' pins
- Version sync: `Package.appxmanifest` Identity Version <-> `.csproj` `<Version>`/`<AssemblyVersion>`/`<FileVersion>`; 4th segment `.0`. CI fails the tag build on mismatch
- Identity `Name`/`Publisher` must match Partner Center exactly
- After identity/name changes delete `bin`, `obj`, `AppPackages` before rebuilding
- Debug builds get `.Debug` package suffix and `(Dev)` display name; a release package blocks debug `-Register` (0x80073CFB), remove it first
Expand Down
5 changes: 0 additions & 5 deletions UnityExtension.sln.DotSettings

This file was deleted.

6 changes: 6 additions & 0 deletions docs/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ If an outdated-package check suggests a newer `Microsoft.WindowsAppSDK`, treat i
If Release packaging fails with `WindowsPackageType=None` + `GenerateAppxPackageOnBuild=true`, remove hard `None` for build path.

If packaging fails with `IL2104` / `NETSDK1144`, check trimming enabled for packaging build path, temporarily disable if needed.

## Build fails: file is locked

`MSB3021` / `MSB3027` "locked by: Unity Extension for Command Palette" means the extension is running inside Command Palette and holds `UnityExtension.exe`. It is not a code error.

Close or unregister the extension (`winapp unregister`) for a normal build, or compile-check into another folder: `dotnet build UnityExtension/UnityExtension.csproj -c Debug -p:Platform=x64 -p:OutDir=<other dir>/`. `-p:UseAppHost=false` fails with `NETSDK1067`.
Loading