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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .nuke

This file was deleted.

128 changes: 128 additions & 0 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Host": {
"type": "string",
"enum": [
"AppVeyor",
"AzurePipelines",
"Bamboo",
"Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
"Jenkins",
"Rider",
"SpaceAutomation",
"TeamCity",
"Terminal",
"TravisCI",
"VisualStudio",
"VSCode"
]
},
"ExecutableTarget": {
"type": "string",
"enum": [
"CiAzureWindows",
"Clean",
"Compile",
"CreateIntermediateNugetPackages",
"CreateNugetPackages",
"Restore"
]
},
"Verbosity": {
"type": "string",
"description": "",
"enum": [
"Verbose",
"Normal",
"Minimal",
"Quiet"
]
},
"NukeBuild": {
"properties": {
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
"Help": {
"type": "boolean",
"description": "Shows the help text for this build assembly"
},
"Host": {
"description": "Host for execution. Default is 'automatic'",
"$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
"Partition": {
"type": "string",
"description": "Partition to use on CI"
},
"Plan": {
"type": "boolean",
"description": "Shows the execution plan (HTML)"
},
"Profile": {
"type": "array",
"description": "Defines the profiles to load",
"items": {
"type": "string"
}
},
"Root": {
"type": "string",
"description": "Root directory during build execution"
},
"Skip": {
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Verbosity": {
"description": "Logging verbosity during build execution. Default is 'Normal'",
"$ref": "#/definitions/Verbosity"
}
}
}
},
"allOf": [
{
"properties": {
"Configuration": {
"type": "string",
"description": "configuration"
},
"ForceNugetVersion": {
"type": "string",
"description": "force-nuget-version"
},
"SkipTests": {
"type": "boolean",
"description": "skip-tests"
},
"Solution": {
"type": "string",
"description": "Path to a solution file that is automatically loaded"
}
}
},
{
"$ref": "#/definitions/NukeBuild"
}
]
}
4 changes: 4 additions & 0 deletions .nuke/parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "./build.schema.json",
"Solution": "src/AvalonStudio.Shell.sln"
}
223 changes: 223 additions & 0 deletions .planning/codebase/ARCHITECTURE.md

Large diffs are not rendered by default.

193 changes: 193 additions & 0 deletions .planning/codebase/CONCERNS.md

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions .planning/codebase/CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Coding Conventions

**Analysis Date:** 2026-08-28

## Naming Patterns

**Files:**
- Use PascalCase C# filenames that name the primary type: `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs`, `src/AvalonStudio.Shell/Controls/StatusBarViewModel.cs`, and `src/ShellExampleApp/MainWindowViewModel.cs`.
- Pair Avalonia views with their code-behind using the same basename (for example, `src/ShellExampleApp/MainWindow.xaml` and `src/ShellExampleApp/MainWindow.xaml.cs`). Several reusable shell resources use the legacy `.paml.cs` suffix, such as `src/AvalonStudio.Shell/ShellView.paml.cs` and `src/AvalonStudio.Shell/Controls/StatusBar.paml.cs`; retain the existing suffix when extending those resources.
- Place types in a directory corresponding to their concern and namespace segment, such as `MVVM`, `Commands`, `Menus`, `Docking`, `Converters`, or `Behaviors` beneath `src/AvalonStudio.Shell.Extensibility/`.

**Functions:**
- Use PascalCase for public, protected, and private methods (`GetMainMenu`, `ResolveCommands`, `LoadLayout`) in `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs` and `src/AvalonStudio.Shell/ShellViewModel.cs`.
- Use `On...` for lifecycle hooks and event-style methods, including `OnOpen`, `OnClose`, `OnSelected`, and `OnFrameworkInitializationCompleted` in `src/AvalonStudio.Shell.Extensibility/Documents/GenericDocumentTabViewModel.cs` and `src/ShellExampleApp/App.paml.cs`.
- Use verb-led extension methods such as `Dock`, `AddOrSelectDocument`, and `GetOrCreate` in `src/AvalonStudio.Shell/DockExtensions.cs` and `src/AvalonStudio.Shell.Extensibility/Shell/IShellExtensions.cs`.

**Variables:**
- Use camelCase for parameters, local variables, and pattern variables (`commandSettings`, `parentItem`, `activatable`) throughout `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs`.
- Use private camelCase fields in most UI/view-model code (`_documents`, `_viewModel`, `modalDialog`) as in `src/AvalonStudio.Shell/ShellViewModel.cs`; legacy and binding-oriented classes also use non-underscore fields (`lineNumber`, `isVisible`) in `src/AvalonStudio.Shell/Controls/StatusBarViewModel.cs` and `src/AvalonStudio.Shell.Extensibility/Dialogs/ModalDialogViewModelBase.cs`. Follow the surrounding file's field style instead of mixing both conventions.
- Use the `s_` prefix for private static mutable fields, as in `s_compositionHost` in `src/AvalonStudio.Shell.Extensibility/IoC.cs`.

**Types:**
- Use PascalCase for classes, interfaces, enums, attributes, and generic parameters. Prefix interfaces with `I` (`IShell`, `IMenuItemFactory`, `IObservableCollection<T>`) in `src/AvalonStudio.Shell.Extensibility/Shell/IShell.cs`, `src/AvalonStudio.Shell.Extensibility/Menus/IMenuItemFactory.cs`, and `src/AvalonStudio.Shell.Extensibility/MVVM/IObservableCollection.cs`.
- Name UI state classes with `ViewModel`, controls/views with `View`, and MEF attribute types with `Export...Attribute`, matching `src/AvalonStudio.Shell/Controls/StatusBarViewModel.cs` and `src/AvalonStudio.Shell.Extensibility/Commands/ExportCommandDefinitionAttribute.cs`.

## Code Style

**Formatting:**
- No repository-root formatter configuration is detected. The only editor configuration is `build/.editorconfig`, so it applies to the build project rather than the `src/` projects.
- In `build/.editorconfig`, omit redundant `this.` qualification and prefer expression-bodied properties, indexers, and accessors. It explicitly permits omitted accessibility modifiers (`dotnet_style_require_accessibility_modifiers = never`).
- Use block-scoped namespaces. Every production C# sample uses `namespace ... { ... }`, for example `src/AvalonStudio.Shell/CompositionRoot.cs` and `Numerge/Numerge/NugetPackageMerger.cs`.
- Place opening braces on a new line. Preserve the local indentation of the file: the repository contains both spaces and tabs, notably tabs in `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs` and spaces in `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs`.
- Prefer concise expression-bodied members where already established (`Title => Platform.AppName` in `src/AvalonStudio.Shell/ShellViewModel.cs` and `BuildAvaloniaApp() => ...` in `src/ShellExampleApp/App.paml.cs`); use full accessors when setters contain notification or guard logic.

**Linting:**
- No project-level analyzer, lint task, `TreatWarningsAsErrors`, `Nullable`, or `LangVersion` configuration is detected in the `.csproj` files or CI pipeline.
- `build/.editorconfig` sets the listed style diagnostics to warning severity. Do not assume additional analyzer enforcement.

## Import Organization

**Order:**
1. Avalonia, Dock, ReactiveUI, and other framework imports are commonly placed first.
2. `AvalonStudio.*` project imports generally follow.
3. `System.*` imports occur last in many UI files, including `src/AvalonStudio.Shell/ShellViewModel.cs` and `src/ShellExampleApp/Commands/ThemeCommands.cs`.

- Import ordering is not mechanically consistent: `src/AvalonStudio.Shell/CompositionRoot.cs` starts with project imports while `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs` starts with `System.*`. Keep imports explicit and preserve the grouping/order of the file being modified; do not introduce a new sorting rule in an isolated change.
- Use direct namespaces rather than a repository-wide global-using mechanism. Static imports are limited to build orchestration in `build/Build.cs`.

**Path Aliases:**
- Not applicable. C# projects reference namespaces directly; no alias/import configuration is detected.

## Error Handling

**Patterns:**
- Let ordinary framework and programming errors propagate. Most public methods do not wrap exceptions, including layout and menu construction in `src/AvalonStudio.Shell/ShellViewModel.cs` and `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs`.
- Catch only a failure with a defined recovery result. `Numerge/Numerge/NugetPackageMerger.cs` catches `MergeAbortedException`, logs its message, and returns `false`; callers in `build/Build.cs` convert `false` to a build failure.
- At extension-discovery boundaries, catch broad load errors and continue loading remaining components, emitting diagnostic text through `System.Console.WriteLine` as in `src/AvalonStudio.Shell/CompositionRoot.cs`.
- Service lookup treats unavailable optional exports as absence: `src/AvalonStudio.Shell.Extensibility/IoC.cs` returns `default` for single lookups and `Enumerable.Empty<T>()` for plural lookup. Callers must safely handle a missing export.
- Use early null guards for optional arguments, as in `RemoveDocument` in `src/AvalonStudio.Shell/ShellViewModel.cs`; avoid adding broad catch-and-ignore blocks.

## Logging

**Framework:** console and Nuke build logging; no application logging abstraction is detected.

**Patterns:**
- Use `Information(...)` for build diagnostics in `build/Build.cs`.
- `Numerge/Numerge/INumergeLogger.cs` defines `Info`, `Error`, and `Warning` for package-merge work; pass an `INumergeLogger` into merger operations rather than writing directly from that library.
- Use `System.Console.WriteLine` only for extension-loading diagnostics in `src/AvalonStudio.Shell/CompositionRoot.cs`. No structured logging provider is configured for shell runtime code.

## Comments

**When to Comment:**
- Comment non-obvious platform, plugin, or framework constraints. `src/AvalonStudio.Shell/CompositionRoot.cs` documents why its custom `AppDomain` loader remains, and `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs` explains the menu-parent registration rule.
- Preserve targeted suppression comments where required, such as the ReSharper suppressions at the top of `Numerge/Numerge/NugetPackageMerger.cs`; do not add blanket suppression files.
- TODO comments exist for explicit pending work (for example `src/AvalonStudio.Shell/CompositionRoot.cs` and `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs`). Keep a TODO adjacent to the constrained behavior and describe the intended outcome.

**JSDoc/TSDoc:**
- Use XML documentation for reusable public/protected collection and framework-extension behavior. `src/AvalonStudio.Shell.Extensibility/MVVM/BindableCollection.cs` documents overridden collection operations and their parameters with `/// <summary>` and `/// <param>`.
- Small view models, services, and straightforward public models generally have no XML comments; avoid redundant documentation for self-evident members.

## Function Design

**Size:**
- Small helpers and model members are preferred, but orchestration classes may own longer stateful flows: `src/AvalonStudio.Shell/ShellViewModel.cs` manages shell lifecycle and docking, and `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs` builds menu trees. Keep UI state transitions with the owning view model/service rather than creating ad-hoc utility classes.

**Parameters:**
- Use constructor injection with `[ImportingConstructor]` for MEF-composed services (`src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs` and `src/AvalonStudio.Shell.Extensibility/MainMenu/MainMenuService.cs`).
- Use optional parameters for feature toggles/default UI behavior (`AddDocument(..., bool temporary = false, bool select = true)` in `src/AvalonStudio.Shell/ShellViewModel.cs`) and generic constraints for document/type factories in the same file.

**Return Values:**
- Return immutable/read-only views of owned mutable state when exposing collections (`Documents => _documents.AsReadOnly()` in `src/AvalonStudio.Shell/ShellViewModel.cs`).
- Return `bool` for expected operation success/failure in the Numerge merge layer (`Numerge/Numerge/NugetPackageMerger.cs`); use exceptions for unrecoverable build failure in `build/Build.cs`.
- For reactive UI properties, update backing fields through `RaiseAndSetIfChanged` or explicitly raise dependent property notifications, following `src/AvalonStudio.Shell/Controls/StatusBarViewModel.cs`.

## Module Design

**Exports:**
- Use one primary public type per PascalCase file. Keep closely coupled helpers/implementations together when they are internal, such as the tab classes in `src/AvalonStudio.Shell/DockExtensions.cs`.
- Expose extension points through interfaces and MEF attributes: `src/AvalonStudio.Shell.Extensibility/Shell/IShell.cs`, `src/AvalonStudio.Shell.Extensibility/Commands/ExportCommandDefinitionAttribute.cs`, and `[Export]/[Shared]` services in `src/AvalonStudio.Shell.Extensibility/Commands/CommandService.cs`.
- Use `internal` for example-app registration holders that should not form public API, as in `src/ShellExampleApp/Commands/ThemeCommands.cs` and `src/ShellExampleApp/MainMenu/ThemeMainMenuItem.cs`.

**Barrel Files:**
- Not applicable. No C# barrel/export-aggregator files are detected; consumers import the concrete namespace/type they need.

---

*Convention analysis: 2026-08-28*
89 changes: 89 additions & 0 deletions .planning/codebase/INTEGRATIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# External Integrations

**Analysis Date:** 2026-08-28

## APIs & External Services

**Package distribution:**
- NuGet.org - package restore source for the .NET solution.
- SDK/Client: .NET SDK/NuGet invoked by `DotNetRestore` in `build/Build.cs`.
- Auth: not configured in `src/nuget.config`; it contains only the public `nuget.org` source.

**Source control and versioning:**
- Git/GitHub repository metadata - NUKE identifies the canonical repository and uses GitVersion metadata during builds.
- SDK/Client: `Nuke.Common` 8.1.4 and `GitVersion.Tool` 6.8.2 in `build/_build.csproj`.
- Auth: not handled by application code; CI checkout credentials are platform-managed.

**CI service:**
- Azure Pipelines - builds every branch/tag on `windows-latest`, installs .NET SDK 8 and 10, runs the NUKE target, and publishes NuGet artifacts.
- SDK/Client: Azure Pipelines YAML tasks in `azure-pipelines.yml`; CI-state detection via `Nuke.Common.CI.AzurePipelines` in `build/BuildParameters.cs`.
- Auth: Azure Pipelines managed identity/token configuration is not defined in this repository.

**Desktop extension boundary:**
- Local MEF extensions - the application discovers `extension.json` manifests under the executable's `Extensions` directory, then loads declared `mefComponents` assemblies.
- SDK/Client: `System.Composition` in `src/AvalonStudio.Shell/CompositionRoot.cs` and `src/AvalonStudio.Shell/ExtensionManager.cs`.
- Auth: none; extensions are filesystem-local rather than a remote API.

No HTTP clients, third-party SaaS SDKs, payment services, messaging providers, or outbound application API calls are detected in `src/`.

## Data Storage

**Databases:**
- Not detected. No ORM, database client, connection string, or database configuration is present in `src/`.

**File Storage:**
- Local filesystem only. The platform initialises a per-application base directory, `Settings` directory, and executable-relative `Extensions` directory in `src/AvalonStudio.Shell.Extensibility/Platforms/Platform.cs`.
- `GlobalSettings.json` is read and written via `src/AvalonStudio.Shell.Extensibility/GlobalSettings/GlobalSettings.cs`.
- `CommandSettings.json` is read and written via `src/AvalonStudio.Shell.Extensibility/Commands/Settings/CommandSettingsService.cs`.
- Extension manifests are parsed from local `extension.json` files by `src/AvalonStudio.Shell/ExtensionManifest.cs`.
- Client: `Newtonsoft.Json` 13.0.3 through the shared serializer in `src/AvalonStudio.Shell.Extensibility/Utils/SerializedObject.cs`.

**Caching:**
- Local application storage only. `AVALON_CACHE_PATH` can relocate the base directory; no distributed cache is configured.

## Authentication & Identity

**Auth Provider:**
- Not detected. `src/` contains no authentication, authorization, OAuth/OpenID, JWT, or identity-provider integration.
- Implementation: not applicable.

## Monitoring & Observability

**Error Tracking:**
- None detected. No error-tracking SDK or telemetry service is referenced by the project files or source.

**Logs:**
- The extension loader writes component-load failures to standard console output in `src/AvalonStudio.Shell/CompositionRoot.cs`.
- NUKE writes build diagnostics through its logging API in `build/Build.cs`; no structured or remote log sink is configured.

## CI/CD & Deployment

**Hosting:**
- Not applicable. This is a desktop-library and NuGet-package repository, not a hosted service.

**CI Pipeline:**
- Azure Pipelines configuration in `azure-pipelines.yml` executes `CiAzureWindows` from `build/Build.cs` and uploads `artifacts/nuget` as a pipeline artifact.
- Packaging is local to the build agent: `build/Build.cs` restores, compiles, packs, and merges packages. No NuGet feed push/publish task is configured.

## Environment Configuration

**Required env vars:**
- None for normal application startup.
- Optional `AVALON_CACHE_PATH` overrides the runtime settings base path in `src/AvalonStudio.Shell.Extensibility/Platforms/Platform.cs`.
- Azure builds expect the non-secret `BUILD_BUILDID` CI variable when generating CI prerelease versions in `build/BuildParameters.cs`.

**Secrets location:**
- No repository-managed secret file or secret-store integration is detected. No `.env` file is present.
- CI and source-control authentication, if needed, remain external to repository code and configuration.

## Webhooks & Callbacks

**Incoming:**
- None detected. The repository contains no web server, endpoint, or webhook handler.

**Outgoing:**
- None detected from application code. The CI pipeline publishes artifacts to Azure Pipelines; it does not define application callbacks.

---

*Integration audit: 2026-08-28*
Loading