Thanks for your interest in XE Local AI Engine. This is an early-stage, Apache-2.0 project maintained by one person, so please keep changes focused and well-described.
- For anything non-trivial, open an issue first to discuss the approach.
- Security issues: do not open a public issue — see SECURITY.md.
- Read
AGENTS.mdfor the repo's conventions and the authoritative validation commands, anddocs/agent-knowledge.mdfor the hard-won invariants (build/analyzer rules, runtime traps) that reading the code won't tell you. - Adding a language? See
docs/translating.md— translating the UI is data plus three small wiring edits, no code changes.
- .NET SDK per
global.json. - .NET 8 runtime for the pinned SBOM and dependency-license tools.
- Node compatible with the React
package.jsonand pnpm through Corepack or a local install. - Python 3 for repository validation and lifecycle scripts.
- The Aspire CLI for AppHost development and integration checks.
- On Linux/WSL,
setsid(normally supplied byutil-linux) for transactionalscripts/dev-start.shcleanup.
These are the real gates — a change isn't done until they pass. The --configuration Release is load-bearing: analyzers (including the "no bare TODO" rule) only run in Release.
Backend:
dotnet tool restore --tool-manifest dotnet-tools.json
scripts/run-backend-tests.shThat one script is the whole backend gate: it builds the solution in Release, then runs every test project
enrolled from XE-Local-AI-Engine.slnx concurrently — XE-Local-AI-Engine.Tests through
scripts/run-tests-memory-safe.sh, the rest as dotnet test at a pinned width — under one build lock, with the
assembly guard on each sibling. CI's siblings leg calls the same script. It is restated from
AGENTS.md, which is authoritative for it. Exit 69 means the build lock was not
acquired and nothing ran. Exit 75 means the result was contaminated and is void; rerun it. Setting COVERAGE_DIR
runs the siblings unguarded — coverage rewrites their assemblies in place, so the guard would call every such run
contaminated — which means a sibling coverage run cannot detect an unwrapped concurrent build.
Frontend CI gates (run dotnet tool restore --tool-manifest dotnet-tools.json once from the repository root, then run
these commands from XE-Local-AI-Engine.Client.React/):
pnpm install --frozen-lockfile
pnpm run openapi:check
pnpm run licenses:check
pnpm run lint
pnpm run test:coverage:check
pnpm run build
pnpm audit --prod --audit-level=highpnpm run lint is the frontend typecheck. openapi:check validates the generated client against the committed spec;
after a backend contract change, follow the live-spec regeneration rules in AGENTS.md before
trusting that drift check.
For frontend dependency-update branches, run pnpm run dependencies:refresh from
XE-Local-AI-Engine.Client.React/. It performs the frozen install first, then collects OpenAPI, generated-license,
validation, and production-build results and reports regenerated tracked files that belong in the same change. A
failed frozen install skips every generator so stale node_modules content cannot produce commit advice. Any
curated license override still requires human verification of its exact evidence, upstream source/tag, and SHA-256.
Release-script changes must also pass:
scripts/lint-release-scripts.shThat default run includes the Pester suite and fails if required linters are missing. End-to-end tests remain opt-in and
ask-gated: scripts/run-e2e-local.sh.
- Branch from and target
develop. - Keep commits focused; write clear messages (Conventional Commits are used across the history).
- Don't commit generated output by hand (the hey-api client is generated), secrets, or runtime data.
- Fill in the pull-request template and note how you validated the change.
By contributing, you agree that your contributions are licensed under the project's Apache-2.0 license.