Skip to content

Latest commit

 

History

History
189 lines (166 loc) · 12.9 KB

File metadata and controls

189 lines (166 loc) · 12.9 KB

AGENTS.md

Purpose

  • This repository contains several related apps: a WinUI 3 client, an ASP.NET Core sync server, NUnit test projects, and a VitePress docs site.
  • Use this file as the fast path for build/test/style guidance before making changes.
  • When repo-specific instruction files conflict with generic habits, prefer the repo-specific instruction files.

Read These First

  • Copilot rule found: .github/copilot-instructions.md.
  • Its instruction is mandatory: before doing anything else, read .kilocode/rules/project-main.md.
  • If you work on the client, also read .kilocode/rules/project-info-galgamemanager.md.
  • If client work changes UI/XAML/custom controls, also read .kilocode/rules/project-info-controls.md.
  • If you work on the server, also read .kilocode/rules/project-info-galgamemanager-server.md.
  • Additional agent docs exist under .github/.clinerules/; they are not Cursor rules, but they contain useful repo knowledge.
  • .github/.clinerules/main.md asks agents to update the project-info knowledge files with general reusable knowledge after finishing a task.
  • No .cursor/rules/ directory or .cursorrules file was found at repo root.

Repository Map

  • GalgameManager/: main WinUI 3 desktop client.
  • GalgameManager.Core/: shared/core .NET library.
  • GalgameManager.Server/: ASP.NET Core Web API sync server.
  • GalgameManager.Test/: client-side NUnit tests.
  • GalgameManager.Server.Test/: server-side NUnit tests.
  • PotatoVN.Doc/: docs site built with VitePress.
  • AuthServer/: separate Flask-based auth component (Deperated, move into GalgameManager.Server).
  • GalgameManager.Tool/: separate C++ utility project.
  • Directory.Build.props: test platform defaults and Windows App SDK test overrides.
  • .editorconfig: main formatting and naming rules.

Environment Notes

  • The client is Windows-specific and uses WinUI 3 plus Windows App SDK.
  • Client packaging/build automation is MSBuild-based, not a simple cross-platform dotnet publish flow.
  • Server targets .NET 8 and is the easiest project to build/run cross-platform.
  • Docs site uses Node/npm inside PotatoVN.Doc/.

Restore

  • From repo root: dotnet restore GalgameManager.sln
  • If touching docs: in PotatoVN.Doc/, run npm install

Build Commands

  • Build everything in the .NET solution: dotnet build GalgameManager.sln
  • Build only the server: dotnet build GalgameManager.Server/GalgameManager.Server.csproj
  • Build only the client project: dotnet build GalgameManager/GalgameManager.csproj
  • Build docs: in PotatoVN.Doc/, run npm run build
  • Start docs dev server: in PotatoVN.Doc/, run npm run dev
  • Preview built docs: in PotatoVN.Doc/, run npm run preview

Client Packaging

  • Canonical CI packaging command is MSBuild-based.
  • Use this pattern from repo workflows for a local x64 sideload package:
msbuild GalgameManager\GalgameManager.csproj /restore "/p:Platform=x64;Configuration=Release;UapAppxPackageBuildMode=SideloadOnly;AppxPackageDir=..\publish\;GenerateAppxPackageOnBuild=true"
  • Signed package generation is CI-oriented and uses .github/workflows/build-signed-package.yml.
  • Pushes to released / flight-released also automatically create a GitHub Release in that workflow (release job): release notes are generated by GitHub Models (openai/gpt-4o) from commits since the previous same-channel release (commits matching fix(<scope>-dev): are filtered out as dev-internal), and the signed MSIX artifacts are attached. Flight releases are tagged v<version>-flight and marked prerelease; stable releases are tagged v<version>.
  • The same workflow's publish_store job publishes to the Microsoft Store via the Microsoft Store Developer CLI (msstore, set up by microsoft/microsoft-store-apppublisher@v1.1). It builds a StoreUpload .msixupload bundle (x86|x64|arm64) with the checked-in Store identity — the sideload identity swap (Set PUBLISHER, icon override) and SignPath signing must NOT be applied to it. released publishes the stable channel; flight-released publishes to the Package Flight in the STORE_FLIGHT_ID repo variable. msstore publish commits the submission and starts certification automatically. For a store-only retry, dispatch the workflow with store_only=true; this skips the build job and therefore also skips its dependent R2 and GitHub Release jobs. Requires PARTNER_CENTER_TENANT_ID / PARTNER_CENTER_CLIENT_ID / PARTNER_CENTER_CLIENT_SECRET / PARTNER_CENTER_SELLER_ID secrets and the STORE_PRODUCT_ID variable.
  • Expect client packaging to require a Windows machine with the proper WinUI/Windows App SDK toolchain.

Lint And Analyzer Guidance

  • No dedicated repo-level lint script was found.
  • Treat dotnet build as the main analyzer/lint pass for C# projects.
  • NUnit analyzers are enabled in both test projects, so test builds also surface style/test issues.
  • Docs site currently has build/dev scripts but no checked-in lint script.
  • Use .editorconfig plus existing file style as the formatting authority.

Test Commands

  • Run all server tests: dotnet test GalgameManager.Server.Test/GalgameManager.Server.Test.csproj
  • Run all client tests: dotnet test GalgameManager.Test/GalgameManager.Test.csproj
  • The client test project automatically uses GalgameManager.Test/test.runsettings.
  • That runsettings file forces x64 and excludes tests in Category("Phraser") by default.
  • Repo rule from .kilocode/rules/project-info-galgamemanager.md: after editing client code, run GalgameManager.Test.
  • If you did not change parser code, you can skip parser tests because they call external services and are slow.

Running A Single Test

  • Preferred pattern: dotnet test <project> --filter "FullyQualifiedName~Namespace.Class.Method"
  • Single server test example:
dotnet test GalgameManager.Server.Test/GalgameManager.Server.Test.csproj --filter "FullyQualifiedName~GalgameManager.Server.Test.Services.GalgameServiceRedirectTests.GetGalgameAsync_WithRedirect_ReturnsTargetGame"
  • Single client test example:
dotnet test GalgameManager.Test/GalgameManager.Test.csproj --filter "FullyQualifiedName~GalgameManager.Test.ProjectTest.Version_ShouldMatch_PackageAppxmanifest"
  • To run a whole test class, filter on the class name instead of the method name.
  • Be aware that the default client runsettings still excludes Phraser tests.
  • Phraser tests hit external APIs; only run them when changing parser/scraper logic.
  • Some upgrade/E2E tests launch the built client executable and are more environment-sensitive.

Server Run Commands

  • Initialize local secrets once: dotnet user-secrets init --project GalgameManager.Server/GalgameManager.Server.csproj
  • Set secrets as needed with: dotnet user-secrets set "Key" "Value" --project GalgameManager.Server/GalgameManager.Server.csproj
  • Run the server locally: dotnet run --project GalgameManager.Server/GalgameManager.Server.csproj
  • Docker-based local deploy is documented in GalgameManager.Server/README.md.
  • The checked-in Docker compose flow lives under GalgameManager.Server/.

Server Configuration Expectations

  • PostgreSQL is required.
  • JWT secret is required and should be at least 64 characters.
  • S3-compatible object storage settings are required for normal operation.
  • GalgameManager.Server/Program.cs validates required configuration at startup and exits early if it is invalid.

Core C# Style

  • Use file-scoped namespaces.
  • Keep using directives outside the namespace.
  • Prefer System.* usings before other usings when organizing imports.
  • Use 4 spaces for indentation; do not use tabs.
  • Preserve final newlines and trim trailing whitespace.
  • Preserve the existing line endings of the file you edit; C# files are typically CRLF here.
  • Use Allman braces for types, methods, properties, and control blocks.
  • Short guard clauses without braces exist in this repo; follow local style when editing nearby code.

Types And Language Features

  • ImplicitUsings is enabled in main projects; do not add redundant usings.
  • Nullable reference types are enabled in client, server, and test projects; respect nullability annotations.
  • GalgameManager.Core does not explicitly enable nullable in its project file, so be extra careful crossing that boundary.
  • Use ? for truly optional references.
  • Use ! sparingly and only when the invariant is already established.
  • Match local style on var versus explicit types; this repo uses both.
  • Explicit types are common for service, model, DTO, and interface variables.
  • var is common when the right-hand side is obvious.
  • Target-typed new(), collection expressions like [], and modern C# syntax are already in use.

Naming Conventions

  • Use PascalCase for classes, structs, enums, methods, properties, and public members.
  • Interfaces should start with I.
  • Private fields should use _camelCase.
  • Injected dependencies are usually stored in private readonly _camelCase fields in the client.
  • Server code often uses primary constructors for controllers and services.
  • Test method names are usually descriptive sentence-style names with underscores.

Dependency Injection And Architecture

  • The overall architecture is MVVM on the client and layered controller/service/repository on the server.
  • Prefer constructor injection over service location.
  • Client ViewModels should keep UI state and orchestration logic, not heavy persistence/networking logic.
  • Business logic should live in services/models rather than in XAML code-behind.
  • Code-behind is acceptable for view-only behavior, event wiring, or platform-specific UI glue.

Client MVVM Patterns

  • Use CommunityToolkit.Mvvm patterns already present in the codebase.
  • Prefer ObservableObject/ObservableRecipient for ViewModels and observable helpers.
  • Prefer [ObservableProperty] over hand-written backing boilerplate when consistent with the file.
  • Prefer [RelayCommand] and related toolkit attributes for commands.
  • Use partial ViewModels where source generators are expected.
  • Follow existing patterns for INavigationAware and service-backed page initialization.

XAML And UI Conventions

  • Prefer x:Bind over classic {Binding} when working with ViewModel-backed pages.
  • Use typed templates with x:DataType where the surrounding file already does so.
  • Reuse existing custom controls and patterns instead of inventing new ones.
  • Common custom controls called out by repo docs: Setting, SettingToggleSwitch, ComboBoxWithI18N, and Panel.
  • Keep UI additions consistent with the existing WinUI 3 style and MVVM structure.

Localization Rules

  • XAML localization uses x:Uid.
  • C# localization typically uses "Key".GetLocalized() or ResourceExtensions.GetLocalized(...).
  • For ContentDialog, localize the root with x:Uid and use .Title, .PrimaryButtonText, and .SecondaryButtonText keys.
  • For child controls, use the expected suffix like .Text, .Label, .Content, or .ToolTipService.ToolTip.
  • Do not directly edit .resw files.
  • Use GalgameManager/Strings/resw_tool.py to search, add, or update localization entries.

Error Handling

  • On the client, catch exceptions at UI/page boundaries and route them through IInfoService when appropriate.
  • InfoService is the central notification/logging path and writes logs through Serilog.
  • Avoid silently swallowing exceptions unless the code is intentionally best-effort and the surrounding style already does so.
  • On the server, validate early and use meaningful exceptions such as ArgumentException and UnauthorizedAccessException.
  • Controllers commonly translate service exceptions into HTTP 400/404 responses.

Test Conventions

  • NUnit is the test framework across both test projects.
  • Server tests commonly use Moq plus EF Core InMemory.
  • GalgameManager.Server.Test/TestBase.cs provides the shared in-memory DataContext setup/teardown pattern.
  • Arrange/Act/Assert comments are common in server tests; keep them if you touch existing tests.
  • Client tests use categories such as Phraser and E2E.
  • Default client test runs exclude Phraser tests via runsettings.
  • Some E2E tests are non-parallel and require a built unpackaged x64 client executable.

Practical Editing Advice

  • Follow the existing file's local style before applying generic preferences.
  • Do not rewrite large areas just to normalize style.
  • When touching localization-backed UI, update strings through resw_tool.py and keep x:Uid naming consistent.
  • When adding settings, follow the existing pattern: setting key, default value, ViewModel property, UI control, localization.
  • When changing server DTOs/entities, expect downstream API client generation and possibly EF migrations to matter.

Quick Pre-PR Checklist

  • Build the relevant project(s).
  • Run the most relevant tests; at minimum run the test project for the area you changed.
  • For client changes, run GalgameManager.Test unless the change is clearly isolated and non-code.
  • For parser changes, explicitly consider Phraser tests.
  • For docs changes, run npm run build in PotatoVN.Doc/.