For contributors and maintainers
Developing Agora
This page covers local builds and validation. Player instructions belong in the in-app guide and website documentation.
Repository map
| Path | Purpose |
|---|---|
crates/agora-core/ | Shared business logic |
crates/agora/ | Standalone CLI |
crates/agora-plugin-api/, crates/agora-plugin-host/ | Plugin contract, and the QuickJS host that runs plugin scripts |
sdk/, examples/plugins/, docs/plugins/ | Plugin author types, runnable examples (exercised by core's end-to-end tests), and the author guide |
desktop/ | Tauri desktop application and React UI |
web/ | Public static directory |
compiler/ | Catalog compiler |
registry/ | Curated catalog source manifests and governance data |
loader-manifests/ | Pinned loader catalog inputs |
scripts/ | Validation and maintenance helpers |
docs/ | User, developer, release, and operator reference |
.kilo/ | AI tooling configuration; .kilo/plans/MASTER_SPEC.md is the engineering blueprint |
BACKLOG.md | Phase-by-phase task tracker |
Keep reusable behavior in agora-core. Desktop, CLI, and MCP hosts should adapt the same services rather than implement parallel business rules.
Prerequisites
- current stable Rust toolchain;
- Node.js and npm supported by the lockfile;
- Python supported by the compiler requirements;
- platform prerequisites required by Tauri;
- Git.
Use the repository lockfiles. Avoid replacing them merely to satisfy a local global-tool mismatch.
Build the CLI
cargo build -p agora-cli
cargo test -p agora-cli
See CLI.md for usage.
Build the desktop application
cd desktop
npm install
npm run build
npm run tauri:dev
A production installer must be tested as a packaged release. Development mode does not prove that compile-time variables, updater metadata, resources, signing, or platform bundles are correct.
Build the website
Generate the root registry-web.json through the local compiler procedure below before building. Static export needs catalog entries to generate the dynamic catalog routes.
cd web
npm install
$env:NEXT_PUBLIC_GITHUB_REPOSITORY = "agora-mc/Agora-Launcher"
npm run build
On bash-compatible shells, export the same variable before npm run build. The site module intentionally rejects an unset repository because release, issue, and source links cannot be constructed safely without it.
The website should remain useful without the desktop application installed. It owns pre-install guidance and shareable documentation, not the complete in-app learning curriculum.
Compile the catalog locally
cd compiler
python -m venv .venv
Activate the environment, then:
pip install -r requirements.txt
python compile.py --skip-sign --no-governance-write --governance-mode off --out ../registry.db
python ../scripts/verify_db.py
Use --skip-sign only for local development. Production clients must not trust unsigned catalog output.
Environment boundaries
Compiler runtime environment
The Python compiler may load .env for local development. Copy .env.example to .env only when local compiler work needs it, and consult .env.example as the canonical variable list.
Secret examples include:
- the Ed25519 private signing key;
- GitHub tokens;
- Discord webhook URLs.
Never commit real values.
Desktop compile-time configuration
The Rust desktop build embeds selected public configuration at compile time. A .env file used by the Python compiler is not automatically a Tauri build environment. Set these as shell variables for local Tauri builds and as repository Actions variables for releases:
| Variable | Purpose | Secret? |
|---|---|---|
AGORA_OAUTH_CLIENT_ID | Public GitHub application client ID used by the governance device flow | No |
AGORA_REGISTRY_PUBKEY | Public Ed25519 key used to verify downloaded catalog signatures | No |
AGORA_REGISTRY_REPO | Catalog repository in owner/repo form | No |
VITE_AGORA_REPOSITORY | Repository used by desktop frontend links | No |
The matching ED25519_PRIVATE_KEY, GitHub tokens, updater signing key, and webhook URLs are secrets. They belong only in the intended protected environment and must never be copied into documentation or screenshots. GitHub device flow does not require embedding a client secret in the native app.
Release workflows must verify the packaged executable can:
- authenticate through intended public client configuration;
- verify the signed catalog;
- synchronize the catalog;
- populate Browse;
- load loader/runtime catalog data.
Do not assume a successful source build proves packaged configuration is present.
Core validation
These mirror .github/workflows/ci-enforcement.yml. Run the ones covering what you touched, and
all of them before calling a substantial change done.
Repository root, hermetic and fast:
python scripts/check_architecture.py && python scripts/check_docs.py && python scripts/check_tauri_bindings.py --check
Rust:
cargo fmt --all --check
cargo clippy -p agora-core -p agora-cli --all-targets --all-features -- -D warnings
cargo test -p agora-core --lib --tests
cargo test -p agora-cli
cargo check -p agora-desktop
Desktop frontend (from desktop/): npm run build && npm run test:unit. npm run build runs the
boundary checks, tsc and vite build. End-to-end tests (npx playwright test) are slower; run
them when touching UI flows.
Compiler (from compiler/, in a venv with requirements.txt):
python compile.py --skip-sign --no-governance-write --governance-mode off --out ../registry.db && python ../scripts/verify_db.py.
A new or renamed Tauri command also needs python scripts/check_tauri_bindings.py --generate.
Gotchas
cargo fmt --all --checkprints diffs to stdout and exits 1; piping it throughtailhides the failure.- CI's frontend job runs
tscandvite builddirectly and skips the boundary checks, sonpm run buildlocally is the only thing that enforces them. - CI uses the latest stable Rust. Clippy runs with
-D warnings, so a lint newer than your local toolchain fails CI while passing locally;rustup updatebefore trusting clippy on lint-sensitive work. - Lockfiles change through their package manager, never by hand. If
npm cicomplains the lock is out of sync, regenerate it with the npm version CI uses (npm 11 / Node 24).
Working-copy notes
web/public/screenshots/*.pngare generated bydesktop/e2e/docs-screenshots.spec.ts. A re-render on another OS changes their bytes; commit them only when the UI they show changed.- History under
registry/archived/is kept, not edited. loader-manifests/is written only by the loader-refresh workflow.
Documentation validation
For a user-visible change:
- update
desktop/src/data/guideContent.ts; - update CLI help and
docs/CLI.mdwhen applicable; - update website docs when first-run behavior changes;
- search for obsolete labels and defaults;
- test all newly documented commands against a temporary data root;
- verify links;
- avoid copying secret-bearing operator commands into player documentation.
Run the hermetic documentation gate:
python scripts/check_docs.py
It checks current internal Markdown links, website routes, guide-topic mappings, product spelling, and known stale claims without making network requests or rewriting files. CLI help-contract checks run under cargo test -p agora-cli.
Documentation screenshots
Documentation screenshots are generated from the current React UI with fixed synthetic Tauri responses. The fixture contains no personal profile, credentials, tokens, private paths, or private packs:
cd desktop
npx playwright test e2e/docs-screenshots.spec.ts --project=chromium --workers=1
Review every generated image under web/public/screenshots/ before publishing. The browser fixture verifies interface copy and layout; use a packaged build with a disposable profile for release smoke testing.
Development data
Prefer a separate data directory for experiments:
agora --data-dir ./tmp/agora-dev paths
Use disposable instances whose purpose is obvious from their name. Never run destructive tests on a real world or the normal user profile.
For a disposable desktop profile, set AGORA_DATA_DIR before starting Tauri:
$env:AGORA_DATA_DIR = Join-Path $env:TEMP "agora-desktop-docs"
cd desktop
npm run tauri:dev
Close Agora before removing that temporary directory. Microsoft credentials use the operating-system credential store and are not isolated by AGORA_DATA_DIR; do not sign in or sign out with a personal account during disposable-profile tests.
Pull-request evidence
Include the smallest relevant evidence:
- tests run;
- packaged or development build used;
- screenshots for UI changes;
- CLI help/output for CLI changes;
- migration or rollback behavior for persistent-state changes;
- timing methodology for performance changes;
- documentation files reviewed.
docs/DEVELOPMENT.mdEdit this page on GitHub