OpenCode Exclusive Configuration This document defines the project structure, patterns, and conventions for all code generation work.
Solution Name: luo.dangxiao
Technology Stack: Avalonia UI + CommunityToolkit.Mvvm + .NET 10.0
Architecture Pattern: MVVM (Model-View-ViewModel)
<TargetFramework>net10.0</TargetFramework>
<Avalonia Version="11.3.12" />
<CommunityToolkit.Mvvm Version="8.4.1" />
<Avalonia.Themes.Fluent Version="11.3.12" />
<Avalonia.Fonts.Inter Version="11.3.12" />luo.dangxiao/
├── luo.dangxiao.common/ # Common utilities, enums, converters
├── luo.dangxiao.interfaces/ # Interface definitions (Controls, Models, Views, ViewModels)
├── luo.dangxiao.models/ # Data models (DTOs, Entities)
├── luo.dangxiao.resources/ # Resource files (Images, Languages, Styles)
├── luo.dangxiao.controls/ # Custom Avalonia controls
├── luo.dangxiao.selfservice/ # Self-service library (Views + ViewModels)
├── luo.dangxiao.selfservice.app/ # Self-service executable entry point
├── luo.dangxiao.cardcenter/ # Card center library (Views + ViewModels)
└── luo.dangxiao.cardcenter.app/ # Card center executable entry point
| Project | Role | Output Type | References |
|---|---|---|---|
luo.dangxiao.common |
Shared utilities library | Library | None |
luo.dangxiao.interfaces |
Contract definitions | Library | None |
luo.dangxiao.models |
Data models (DTOs, Entities) | Library | None |
luo.dangxiao.resources |
Resource files (Images, Languages, Styles) | Library | Avalonia |
luo.dangxiao.controls |
Custom Avalonia controls | Library | Avalonia, luo.dangxiao.interfaces |
luo.dangxiao.selfservice |
Self-service UI module | Library | Avalonia, CommunityToolkit.Mvvm, luo.dangxiao.common, luo.dangxiao.interfaces, luo.dangxiao.models, luo.dangxiao.resources, luo.dangxiao.controls |
luo.dangxiao.selfservice.app |
Self-service application | WinExe | luo.dangxiao.selfservice, Avalonia.Desktop |
luo.dangxiao.cardcenter |
Card center UI module | Library | Avalonia, CommunityToolkit.Mvvm, luo.dangxiao.common, luo.dangxiao.interfaces, luo.dangxiao.models, luo.dangxiao.resources, luo.dangxiao.controls |
luo.dangxiao.cardcenter.app |
Card center application | WinExe | luo.dangxiao.cardcenter, Avalonia.Desktop |
Workspace Root: /mnt/d/github/luo-dangxiao/src/
Source Code:
- /mnt/d/github/luo-dangxiao/src/{project-name}/
Configuration:
- /mnt/d/github/luo-dangxiao/src/AGENTS.md (this file)
{project}/
├── *.csproj # Project file
├── {Folder}/ # Organized by feature/type
│ └── *.cs
└── (Optional) *.axaml # For controls project only
{project}.app/
├── *.csproj # Project file
├── app.manifest # Windows manifest
├── Program.cs # Entry point
└── (No other folders - keep minimal)
| Folder | Purpose | Allowed Projects |
|---|---|---|
Utils/ |
Utility/helper classes | luo.dangxiao.common only |
Enum/ |
Enumeration definitions | luo.dangxiao.common only |
Converter/ |
IValueConverter implementations | luo.dangxiao.common only |
Models/ |
Data models/DTOs | luo.dangxiao.models, luo.dangxiao.interfaces |
Controls/ |
Custom control definitions | luo.dangxiao.controls, luo.dangxiao.interfaces |
Images/ |
Image resources (png, jpg, svg, ico) | luo.dangxiao.resources only |
Languages/ |
Localization resource files (.resx) | luo.dangxiao.resources only |
Styles/ |
Avalonia style files (.axaml) | luo.dangxiao.resources only |
Views/ |
Avalonia views (.axaml + .axaml.cs) | luo.dangxiao.selfservice, luo.dangxiao.cardcenter |
ViewModels/ |
View model classes | luo.dangxiao.selfservice, luo.dangxiao.cardcenter |
luo.dangxiao.{modulename} # Library projects
luo.dangxiao.{modulename}.app # Application entry points
// MUST match project name exactly
namespace luo.dangxiao.common.Utils;
namespace luo.dangxiao.selfservice.ViewModels;
namespace luo.dangxiao.selfservice.Views;
namespace luo.dangxiao.interfaces.Controls;| Type | Pattern | Example |
|---|---|---|
| Class | PascalCase | MainWindowViewModel.cs |
| View (AXAML) | {Name}View.axaml | HomePageView.axaml |
| View Code-behind | {Name}View.axaml.cs | HomePageView.axaml.cs |
| Utility | PascalCase | DoubleUtil.cs |
| Interface | IPascalCase | IMainWindowViewModel.cs |
| Enum | PascalCase | ApplicationState.cs |
| Converter | PascalCaseConverter | BoolToVisibilityConverter.cs |
| Colors | Colors.axaml | Colors.axaml (in Styles/ folder) |
| Type | Pattern | Example |
|---|---|---|
| ViewModel | {Name}ViewModel | MainWindowViewModel |
| View | {Name}View | HomePageView (Window/UserControl) |
| Base Class | {Name}Base | ViewModelBase |
| Utility | {Name}Util | DoubleUtil, EnumUtility |
| Interface | I{Name} | IMainWindowViewModel |
| Converter | {Name}Converter | BoolToVisibilityConverter |
| Enum | PascalCase | ApplicationState |
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace luo.dangxiao.{module}.ViewModels;
/// <summary>
/// ViewModel for {ViewName}
/// </summary>
public partial class {ViewName}ViewModel : ViewModelBase
{
[ObservableProperty]
private string _fieldName;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ComputedProperty))]
private int _otherField;
public string ComputedProperty => $"{_otherField} items";
[RelayCommand]
private void DoSomething()
{
// Command implementation
}
}RULES:
- MUST inherit from
ViewModelBase(not ObservableObject directly) - MUST use
[ObservableProperty]for auto-generated properties - MUST use
[RelayCommand]for commands - MUST mark class as
partialfor source generators - MUST use
_camelCasefor backing fields
using CommunityToolkit.Mvvm.ComponentModel;
namespace luo.dangxiao.{module}.ViewModels;
/// <summary>
/// Base class for all ViewModels
/// </summary>
public abstract class ViewModelBase : ObservableObject
{
}<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:luo.dangxiao.{module}.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="luo.dangxiao.{module}.Views.{ViewName}"
x:DataType="vm:{ViewName}ViewModel"
Title="{ViewName}">
<Design.DataContext>
<vm:{ViewName}ViewModel/>
</Design.DataContext>
<!-- View content -->
</Window>RULES:
- MUST declare
x:DataTypefor compile-time binding validation - MUST include
Design.DataContextfor IDE preview - MUST use
vm:prefix for ViewModel namespaces - MUST set
mc:Ignorable="d"for design-time attributes
using Avalonia.Controls;
namespace luo.dangxiao.{module}.Views;
/// <summary>
/// View for {ViewName}
/// </summary>
public partial class {ViewName} : Window // or UserControl
{
public {ViewName}()
{
InitializeComponent();
}
}using Avalonia;
using luo.dangxiao.{module};
namespace luo.dangxiao.{module}.app;
/// <summary>
/// Entry point for {Module} application
/// </summary>
internal sealed class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
}<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="luo.dangxiao.{module}.App"
RequestedThemeVariant="Default">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>namespace luo.dangxiao.common.Utils;
/// <summary>
/// Utility methods for {purpose}
/// </summary>
public static class {Name}Util
{
// Static methods only
}using System.ComponentModel;
namespace luo.dangxiao.common.Enum;
/// <summary>
/// {Description}
/// </summary>
public enum {Name}
{
[Description("Description text")]
Value1,
[Description("Another description")]
Value2
}using Avalonia.Data.Converters;
using System;
using System.Globalization;
namespace luo.dangxiao.common.Converter;
/// <summary>
/// Converts {source type} to {target type}
/// </summary>
public class {Name}Converter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// Implementation
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// Implementation
}
}namespace luo.dangxiao.models;
/// <summary>
/// Data model for {EntityName}
/// </summary>
public class {EntityName}
{
/// <summary>
/// Unique identifier
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// Creation timestamp
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last modification timestamp
/// </summary>
public DateTime? ModifiedAt { get; set; }
// Add entity-specific properties here
}RULES:
- Models are simple POCOs (Plain Old CLR Objects)
- Use nullable reference types where appropriate
- Include standard audit fields (Id, CreatedAt, ModifiedAt)
- Use init-only setters for immutable properties
Resource File Structure:
Languages/
├── Language.resx # Default (en-US)
├── Language.zh-Hans.resx # Simplified Chinese
├── Language.zh-Hant.resx # Traditional Chinese
└── Language.{culture}.resx # Additional cultures
Usage in XAML:
<Window xmlns:lang="using:luo.dangxiao.resources.Languages">
<Button Content="{x:Static lang:Language.Button_OK}"/>
</Window>Usage in Code-Behind:
using luo.dangxiao.resources.Languages;
var message = Language.Msg_Success;Naming Convention for Resource Keys:
App_- Application-level stringsButton_- Button labelsLabel_- Field labelsMsg_- Messages and notificationsNav_- Navigation itemsError_- Error messagesTitle_- Window/dialog titles
| Project | Can Reference |
|---|---|
luo.dangxiao.common |
None (base layer) |
luo.dangxiao.interfaces |
None (contract layer) |
luo.dangxiao.models |
None (data layer) |
luo.dangxiao.resources |
None (resource layer) |
luo.dangxiao.controls |
luo.dangxiao.interfaces |
luo.dangxiao.selfservice |
luo.dangxiao.common, luo.dangxiao.interfaces, luo.dangxiao.models, luo.dangxiao.resources, luo.dangxiao.controls |
luo.dangxiao.cardcenter |
luo.dangxiao.common, luo.dangxiao.interfaces, luo.dangxiao.models, luo.dangxiao.resources, luo.dangxiao.controls |
luo.dangxiao.selfservice.app |
luo.dangxiao.selfservice only |
luo.dangxiao.cardcenter.app |
luo.dangxiao.cardcenter only |
.app -> Module -> controls -> interfaces
-> models (DTOs/Entities)
-> resources (Images/Languages/Styles)
-> common (shared utilities)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.12" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.12" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
</ItemGroup>
<!-- For views with code-behind -->
<ItemGroup>
<Compile Update="Views\*.axaml.cs">
<SubType>Code</SubType>
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Views\*.axaml">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<!-- Project references -->
<ItemGroup>
<ProjectReference Include="..\luo.dangxiao.common\luo.dangxiao.common.csproj" />
<ProjectReference Include="..\luo.dangxiao.interfaces\luo.dangxiao.interfaces.csproj" />
<ProjectReference Include="..\luo.dangxiao.controls\luo.dangxiao.controls.csproj" />
<ProjectReference Include="..\luo.dangxiao.models\luo.dangxiao.models.csproj" />
<ProjectReference Include="..\luo.dangxiao.resources\luo.dangxiao.resources.csproj" />
</ItemGroup>
</Project><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.12" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.12" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.12" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.12" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\luo.dangxiao.{module}\luo.dangxiao.{module}.csproj" />
</ItemGroup>
</Project><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.12" />
</ItemGroup>
<!-- Resource files configuration -->
<ItemGroup>
<EmbeddedResource Update="Languages\*.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>%(Filename).Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Update="Languages\*.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>%(Filename).resx</DependentUpon>
</Compile>
</ItemGroup>
<!-- Images as content -->
<ItemGroup>
<None Update="Images\**\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<!-- Styles as content -->
<ItemGroup>
<None Update="Styles\*.axaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>MUST document:
- All public classes
- All public methods
- All public properties
- Complex algorithms
- Non-obvious behavior
Documentation Format:
/// <summary>
/// Brief description of what this does
/// </summary>
/// <param name="paramName">Description of parameter</param>
/// <returns>Description of return value</returns>
/// <exception cref="ExceptionType">When thrown</exception>Optional but recommended:
// Copyright (c) luo.dangxiao. All rights reserved.
// Licensed under the MIT License.- Create both
.axamland.axaml.csfiles - Place in
{module}/Views/folder - Generate corresponding ViewModel in
{module}/ViewModels/ - Follow AXAML template exactly
- Set
x:DataTypeto ViewModel type
- Inherit from
ViewModelBase - Use
[ObservableProperty]for bindable properties - Use
[RelayCommand]for commands - Mark class as
partial - Place in
{module}/ViewModels/folder
- Place in
luo.dangxiao.common/Utils/ - Use
static classwithUtilsuffix - Follow existing utility patterns
- Place in
luo.dangxiao.common/Enum/ - Use
[Description]attribute for display text - Use
EnumUtility.GetName()for display
- Place in
luo.dangxiao.common/Converter/ - Implement
IValueConverter - Use
Convertersuffix
- Place in
luo.dangxiao.models/ - Use standard POCO pattern (template 5.10)
- Include audit fields (Id, CreatedAt, ModifiedAt)
- Use nullable types for optional properties
- Add entries to
luo.dangxiao.resources/Languages/Language.resx - Add translated entries to
Language.zh-Hans.resx - Follow naming convention:
Category_Descriptor(e.g.,Button_OK,Msg_Success) - Regenerate Designer.cs files
Before declaring code complete, verify:
- Project references follow dependency rules (Section 6)
- Namespaces match project names (Section 4.2)
- ViewModels inherit from
ViewModelBase - ViewModels marked
partial - AXAML files have
x:DataTypedeclared - Package versions match Section 1.1
- Code follows templates in Section 5
- Public APIs are documented (Section 8)
- All files in correct folders (Section 3)
- Models include standard audit fields (Id, CreatedAt, ModifiedAt)
- Localization resources updated for all supported cultures
- Create
Views/{Name}.axaml(use template 5.3) - Create
Views/{Name}.axaml.cs(use template 5.4) - Create
ViewModels/{Name}ViewModel.cs(use template 5.1) - Update
.csprojif needed (template 7.1)
- Create
Utils/{Name}Util.csinluo.dangxiao.common - Use template 5.7
- Reference from other projects via
luo.dangxiao.common.Utils
- Create
Models/{Name}.csinluo.dangxiao.models - Use template 5.10
- Include Id, CreatedAt, ModifiedAt fields
- Reference from other projects via
luo.dangxiao.models
- Add entries to
Languages/Language.resx(English) - Add translations to
Languages/Language.zh-Hans.resx(Simplified Chinese) - Follow naming:
Category_Descriptor(e.g.,Button_OK) - Reference in code via
luo.dangxiao.resources.Languages
- Create
Styles/Colors.axamlinluo.dangxiao.resources - Define all color resources as
Colorelements withx:Key - Create corresponding
SolidColorBrushandLinearGradientBrushresources - Reference in XAML via
{StaticResource ResourceKey} - Include in App.axaml:
<StyleInclude Source="avares://luo.dangxiao.resources/Styles/Colors.axaml"/>
Color Naming Convention:
- Primary colors:
Primary{Name}Color(e.g.,PrimaryRedColor) - Secondary colors:
Secondary{Name}Color(e.g.,SecondaryGoldColor) - Background colors:
Background{Name}Color(e.g.,BackgroundCreamColor) - Text colors:
Text{Name}Color(e.g.,TextPrimaryColor) - Status colors:
{Status}Color(e.g.,SuccessColor,ErrorColor) - Brush resources:
{ColorName}Brush(e.g.,PrimaryRedBrush)
- Create
luo.dangxiao.admin/(use template 7.1) - Create
luo.dangxiao.admin.app/(use template 7.2) - Follow folder structure:
Views/,ViewModels/ - Add references per Section 6 rules
Last Updated: 2025-03-23
Maintainer: OpenCode Agent
Version: 1.1