{"owner":"flybywiresim","repo":"aircraft","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file applies to the entire repository. More specific `AGENTS.md` files, if added below this directory, override it for their subtree.\n\n## Repository map\n\n- `fbw-a32nx/`: A320neo-specific package, instruments, TypeScript systems, models, behaviors, and WASM.\n- `fbw-a380x/`: A380-specific package, instruments, TypeScript systems, and WASM.\n- `fbw-common/`: code shared by both aircraft, including SDK utilities, instrument components, typings, tests, and common WASM crates.\n- `fbw-ingamepanels-checklist-fix/`: separate in-game panel package.\n- `scripts/`: setup, build, packaging, lint, and development-container entry points.\n- `tools/`: standalone project utilities.\n- `large-files/`: Git submodule for large binary assets. Do not modify its contents or submodule pointer unless the task explicitly concerns those assets.\n- `igniter.config.mjs`: top-level build graph. `fbw-a32nx/mach.config.js` and `fbw-a380x/mach.config.js` register instrument entry points.\n- `fbw-*/out/`, `build/`, `target/`, instrument bundles, and generated localization files are build products; change their source or generator rather than generated output.\n\nPut aircraft-independent behavior in `fbw-common` when both aircraft genuinely share the same contract. Keep aircraft geometry, configuration, simvars, and system behavior in the relevant aircraft tree. Preserve existing path aliases such as `@flybywiresim/*`, `@shared/*`, and `@instruments/*` instead of adding long relative imports.\n\n## Generated sources\n\n- Do not modify generated behavior XML sources in `generated` folders.\n- Do not modify the generated `model/` folders in the fly-by-wire WASM modules: `fbw-a32nx/src/wasm/fbw_a320/src/model/` and `fbw-a380x/src/wasm/fbw_a380/src/model/`.\n\n## Environment and build system\n\nThe pinned Docker development environment is the source of truth for full builds and CI-equivalent validation. Initialize the submodule before building.\n\n```sh\ngit submodule update --init\n./scripts/dev-env/run.sh ./scripts/setup.sh\n./scripts/dev-env/run.sh ./scripts/build.sh\n```\n\nOn Windows, use `scripts\\dev-env\\run.cmd` in place of `run.sh`. Setup runs `pnpm install`; keep `pnpm-lock.yaml` synchronized and do not introduce another package manager lockfile.\n\n**Important:** Set `FBW_TYPECHECK=1` in the environment to enable TypeScript checks. This must be done before code is considered deliverable.\n\nUseful scoped commands:\n\n```sh\n# Full aircraft builds (the -r expression selects Igniter tasks)\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a32nx\"\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a380x\"\n\n# Instrument-only development, from the selected aircraft directory\npnpm exec mach build -f PFD\npnpm exec mach watch -f PFD\n\n# Or from the repository root\npnpm exec mach build --config fbw-a32nx/mach.config.js --work-in-config-dir -f PFD\n```\n\nMach/esbuild contains native binaries. If dependencies were installed inside the Linux container, host-side Mach can fail; run it in a matching environment or reinstall the host binary as described in the instrument README. Full builds also require the initialized `large-files` submodule. Avoid a full two-aircraft build when a focused instrument, crate, or test validates the change.\n\nThe Rust workspace is defined by the root `Cargo.toml`, pinned by `rust-toolchain.toml`, and targets `wasm32-wasip1`. C++/WASM code is built through the root CMake configuration and `scripts/build-cmake.sh`.\n\n## React versus FSComponent\n\nThis repository has two unrelated JSX runtimes. A `.tsx` suffix alone does not identify which one a file uses. Before editing or moving instrument code, inspect the instrument's nearest `tsconfig.json`, its entry point, and its registration in the aircraft `mach.config.js`.\n\n### MSFS SDK FSComponent instruments\n\nThe normal instrument tsconfig uses:\n\n```json\n\"jsxFactory\": \"FSComponent.buildComponent\",\n\"jsxFragmentFactory\": \"FSComponent.Fragment\"\n```\n\nMach registers these with `msfsAvionicsInstrument(...)`. Current examples include PFD, ND, EWD, FCU, Clock, MFD, OANC, and SDv2 (the exact lists differ by aircraft).\n\n- Use `DisplayComponent`, `FSComponent`, `VNode`, `Subject`/`MappedSubject`, event-bus publishers and subscribers, and SDK lifecycle methods.\n- Keep `FSComponent` imported when JSX needs the configured factory; ESLint intentionally exempts that name from unused-variable reporting.\n- Use FSComponent JSX conventions, notably `class`, subscribable attributes, and SDK refs. Do not mechanically convert them to React's `className` or React refs.\n- Create subscriptions in the appropriate lifecycle phase (usually `onAfterRender`). Retain subscriptions/resources and destroy them in `destroy()`, then call `super.destroy()`.\n- Mount with `FSComponent.render(...)` from the base instrument's `connectedCallback`; drive publishers/backplanes from the instrument update lifecycle.\n- Do not use React hooks, React context, `ReactDOM`, or React-only libraries in an FSComponent tree.\n\n### React instruments\n\nReact instruments extend `tsconfig.react.json`, whose JSX factory is `React.createElement`, and Mach registers them with `reactInstrument(...)`. Examples include EFB and BAT plus legacy or aircraft-specific instruments such as A32NX SD and A380X SD/RTPI.\n\n- Use React 17 conventions: `className`, React refs, hooks, context/providers, and the existing React render helper.\n- Use `@flybywiresim/fbw-sdk-react` hooks where established. Clean up timers, listeners, and subscriptions in the `useEffect` cleanup function.\n- Follow the Rules of Hooks even though the root ESLint configuration cannot yet enforce every React rule.\n- Do not pass React elements or hooks into an FSComponent subtree. Share framework-neutral data/model code when logic is needed by both runtimes.\n- New instruments should use FSComponent; the instrument README explicitly says to avoid React for new instruments unless the development team agrees otherwise.\n\nWhen adding an instrument, update the appropriate `mach.config.js`, choose the correct helper, add the matching local tsconfig inheritance, and follow a neighboring instrument's base-instrument registration and package layout.\n\n## TypeScript and JavaScript conventions\n\n- TypeScript is preferred in `src/systems`; JavaScript is mainly for build/config scripts and legacy exceptions.\n- The simulator runtime targets ES2017/Coherent GT. Do not assume Node.js APIs or modern browser APIs are available in shipped instrument code.\n- Use 2 spaces, single quotes, trailing commas where Prettier emits them, and a 120-column print width. Let repository ESLint/Prettier rules decide formatting.\n- The TypeScript strictness plugin is incremental. Do not add `// @ts-strict-ignore` to new files or broaden an existing exemption merely to silence errors; keep new and modified code strictly typed where practical.\n- Prefix intentionally unused parameters or locals with `_`. Do not add blanket ESLint disables when a narrow line-level exception is sufficient.\n- Preserve the copyright/SPDX header style used by neighboring files. When modifying a file with a copyright header, extend its ending year to the current calendar year; retain existing holders and SPDX identifiers.\n- Keep simulator reads/writes, event-bus topics, ARINC validity handling, units, and update frequency explicit. Avoid polling faster than the source data requires.\n- Follow local naming and file organization. Instrument folders contain domain-specific conventions that are more authoritative than distant examples.\n\n## Rust and C++ conventions\n\n- Format Rust with `cargo fmt`; keep Clippy warning-free under the flags in `scripts/lint-rust.sh`.\n- Add Rust unit tests close to the module under test. Use package-scoped commands during iteration, then workspace validation when warranted.\n- Follow the root `.clang-format` (Chromium base, two-space indentation, 140-column limit) or a closer subtree override for C/C++.\n- Preserve physical units and simulation update semantics. Prefer the existing typed-unit and simulation-element abstractions over raw numeric values.\n\n## Tests and validation\n\nRun the smallest relevant checks first, followed by the broader checks justified by the change.\n\n```sh\n# TypeScript/JavaScript\npnpm lint\npnpm test\npnpm exec vitest run path/to/file.spec.ts\n\n# Rust (CI-equivalent scripts)\n./scripts/dev-env/run.sh scripts/lint-rust.sh\n./scripts/dev-env/run.sh scripts/test-rust.sh\n\n# Faster scoped Rust iteration\ncargo test -p <package>\ncargo clippy -p <package> --all-targets --all-features -- -D warnings -A clippy::too_many_arguments -A deprecated\n```\n\nTypeScript tests are colocated as `*.spec.ts`/`*.spec.tsx`; Vitest uses `jsdom` and `fbw-common/src/jest/setupJestMock.ts`. Add regression tests for pure logic and system behavior where feasible. UI or simulator-coupled changes should also receive a focused Mach build and an in-simulator check when behavior cannot be covered outside MSFS. Report which checks ran and which could not run.\n\nBefore handing off a change:\n\n1. Review `git diff` and do not include build products, secrets, `.env` changes, or unrelated user modifications.\n2. Run lint/tests for touched languages and a focused build for affected instruments or aircraft.\n3. Keep `pnpm-lock.yaml` and `Cargo.lock` changes intentional.\n4. For contributions, follow `.github/Contributing.md`: realism changes need supporting documentation, commits/PR titles use Conventional Commits, and user-visible changes require an entry in `.github/CHANGELOG.md`.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file applies to the entire repository. More specific `AGENTS.md` files, if added below this directory, override it for their subtree.\n\n## Repository map\n\n- `fbw-a32nx/`: A320neo-specific package, instruments, TypeScript systems, models, behaviors, and WASM.\n- `fbw-a380x/`: A380-specific package, instruments, TypeScript systems, and WASM.\n- `fbw-common/`: code shared by both aircraft, including SDK utilities, instrument components, typings, tests, and common WASM crates.\n- `fbw-ingamepanels-checklist-fix/`: separate in-game panel package.\n- `scripts/`: setup, build, packaging, lint, and development-container entry points.\n- `tools/`: standalone project utilities.\n- `large-files/`: Git submodule for large binary assets. Do not modify its contents or submodule pointer unless the task explicitly concerns those assets.\n- `igniter.config.mjs`: top-level build graph. `fbw-a32nx/mach.config.js` and `fbw-a380x/mach.config.js` register instrument entry points.\n- `fbw-*/out/`, `build/`, `target/`, instrument bundles, and generated localization files are build products; change their source or generator rather than generated output.\n\nPut aircraft-independent behavior in `fbw-common` when both aircraft genuinely share the same contract. Keep aircraft geometry, configuration, simvars, and system behavior in the relevant aircraft tree. Preserve existing path aliases such as `@flybywiresim/*`, `@shared/*`, and `@instruments/*` instead of adding long relative imports.\n\n## Generated sources\n\n- Do not modify generated behavior XML sources in `generated` folders.\n- Do not modify the generated `model/` folders in the fly-by-wire WASM modules: `fbw-a32nx/src/wasm/fbw_a320/src/model/` and `fbw-a380x/src/wasm/fbw_a380/src/model/`.\n\n## Environment and build system\n\nThe pinned Docker development environment is the source of truth for full builds and CI-equivalent validation. Initialize the submodule before building.\n\n```sh\ngit submodule update --init\n./scripts/dev-env/run.sh ./scripts/setup.sh\n./scripts/dev-env/run.sh ./scripts/build.sh\n```\n\nOn Windows, use `scripts\\dev-env\\run.cmd` in place of `run.sh`. Setup runs `pnpm install`; keep `pnpm-lock.yaml` synchronized and do not introduce another package manager lockfile.\n\n**Important:** Set `FBW_TYPECHECK=1` in the environment to enable TypeScript checks. This must be done before code is considered deliverable.\n\nUseful scoped commands:\n\n```sh\n# Full aircraft builds (the -r expression selects Igniter tasks)\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a32nx\"\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a380x\"\n\n# Instrument-only development, from the selected aircraft directory\npnpm exec mach build -f PFD\npnpm exec mach watch -f PFD\n\n# Or from the repository root\npnpm exec mach build --config fbw-a32nx/mach.config.js --work-in-config-dir -f PFD\n```\n\nMach/esbuild contains native binaries. If dependencies were installed inside the Linux container, host-side Mach can fail; run it in a matching environment or reinstall the host binary as described in the instrument README. Full builds also require the initialized `large-files` submodule. Avoid a full two-aircraft build when a focused instrument, crate, or test validates the change.\n\nThe Rust workspace is defined by the root `Cargo.toml`, pinned by `rust-toolchain.toml`, and targets `wasm32-wasip1`. C++/WASM code is built through the root CMake configuration and `scripts/build-cmake.sh`.\n\n## React versus FSComponent\n\nThis repository has two unrelated JSX runtimes. A `.tsx` suffix alone does not identify which one a file uses. Before editing or moving instrument code, inspect the instrument's nearest `tsconfig.json`, its entry point, and its registration in the aircraft `mach.config.js`.\n\n### MSFS SDK FSComponent instruments\n\nThe normal instrument tsconfig uses:\n\n```json\n\"jsxFactory\": \"FSComponent.buildComponent\",\n\"jsxFragmentFactory\": \"FSComponent.Fragment\"\n```\n\nMach registers these with `msfsAvionicsInstrument(...)`. Current examples include PFD, ND, EWD, FCU, Clock, MFD, OANC, and SDv2 (the exact lists differ by aircraft).\n\n- Use `DisplayComponent`, `FSComponent`, `VNode`, `Subject`/`MappedSubject`, event-bus publishers and subscribers, and SDK lifecycle methods.\n- Keep `FSComponent` imported when JSX needs the configured factory; ESLint intentionally exempts that name from unused-variable reporting.\n- Use FSComponent JSX conventions, notably `class`, subscribable attributes, and SDK refs. Do not mechanically convert them to React's `className` or React refs.\n- Create subscriptions in the appropriate lifecycle phase (usually `onAfterRender`). Retain subscriptions/resources and destroy them in `destroy()`, then call `super.destroy()`.\n- Mount with `FSComponent.render(...)` from the base instrument's `connectedCallback`; drive publishers/backplanes from the instrument update lifecycle.\n- Do not use React hooks, React context, `ReactDOM`, or React-only libraries in an FSComponent tree.\n\n### React instruments\n\nReact instruments extend `tsconfig.react.json`, whose JSX factory is `React.createElement`, and Mach registers them with `reactInstrument(...)`. Examples include EFB and BAT plus legacy or aircraft-specific instruments such as A32NX SD and A380X SD/RTPI.\n\n- Use React 17 conventions: `className`, React refs, hooks, context/providers, and the existing React render helper.\n- Use `@flybywiresim/fbw-sdk-react` hooks where established. Clean up timers, listeners, and subscriptions in the `useEffect` cleanup function.\n- Follow the Rules of Hooks even though the root ESLint configuration cannot yet enforce every React rule.\n- Do not pass React elements or hooks into an FSComponent subtree. Share framework-neutral data/model code when logic is needed by both runtimes.\n- New instruments should use FSComponent; the instrument README explicitly says to avoid React for new instruments unless the development team agrees otherwise.\n\nWhen adding an instrument, update the appropriate `mach.config.js`, choose the correct helper, add the matching local tsconfig inheritance, and follow a neighboring instrument's base-instrument registration and package layout.\n\n## TypeScript and JavaScript conventions\n\n- TypeScript is preferred in `src/systems`; JavaScript is mainly for build/config scripts and legacy exceptions.\n- The simulator runtime targets ES2017/Coherent GT. Do not assume Node.js APIs or modern browser APIs are available in shipped instrument code.\n- Use 2 spaces, single quotes, trailing commas where Prettier emits them, and a 120-column print width. Let repository ESLint/Prettier rules decide formatting.\n- The TypeScript strictness plugin is incremental. Do not add `// @ts-strict-ignore` to new files or broaden an existing exemption merely to silence errors; keep new and modified code strictly typed where practical.\n- Prefix intentionally unused parameters or locals with `_`. Do not add blanket ESLint disables when a narrow line-level exception is sufficient.\n- Preserve the copyright/SPDX header style used by neighboring files. When modifying a file with a copyright header, extend its ending year to the current calendar year; retain existing holders and SPDX identifiers.\n- Keep simulator reads/writes, event-bus topics, ARINC validity handling, units, and update frequency explicit. Avoid polling faster than the source data requires.\n- Follow local naming and file organization. Instrument folders contain domain-specific conventions that are more authoritative than distant examples.\n\n## Rust and C++ conventions\n\n- Format Rust with `cargo fmt`; keep Clippy warning-free under the flags in `scripts/lint-rust.sh`.\n- Add Rust unit tests close to the module under test. Use package-scoped commands during iteration, then workspace validation when warranted.\n- Follow the root `.clang-format` (Chromium base, two-space indentation, 140-column limit) or a closer subtree override for C/C++.\n- Preserve physical units and simulation update semantics. Prefer the existing typed-unit and simulation-element abstractions over raw numeric values.\n\n## Tests and validation\n\nRun the smallest relevant checks first, followed by the broader checks justified by the change.\n\n```sh\n# TypeScript/JavaScript\npnpm lint\npnpm test\npnpm exec vitest run path/to/file.spec.ts\n\n# Rust (CI-equivalent scripts)\n./scripts/dev-env/run.sh scripts/lint-rust.sh\n./scripts/dev-env/run.sh scripts/test-rust.sh\n\n# Faster scoped Rust iteration\ncargo test -p <package>\ncargo clippy -p <package> --all-targets --all-features -- -D warnings -A clippy::too_many_arguments -A deprecated\n```\n\nTypeScript tests are colocated as `*.spec.ts`/`*.spec.tsx`; Vitest uses `jsdom` and `fbw-common/src/jest/setupJestMock.ts`. Add regression tests for pure logic and system behavior where feasible. UI or simulator-coupled changes should also receive a focused Mach build and an in-simulator check when behavior cannot be covered outside MSFS. Report which checks ran and which could not run.\n\nBefore handing off a change:\n\n1. Review `git diff` and do not include build products, secrets, `.env` changes, or unrelated user modifications.\n2. Run lint/tests for touched languages and a focused build for affected instruments or aircraft.\n3. Keep `pnpm-lock.yaml` and `Cargo.lock` changes intentional.\n4. For contributions, follow `.github/Contributing.md`: realism changes need supporting documentation, commits/PR titles use Conventional Commits, and user-visible changes require an entry in `.github/CHANGELOG.md`.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file applies to the entire repository. More specific `AGENTS.md` files, if added below this directory, override it for their subtree.\n\n## Repository map\n\n- `fbw-a32nx/`: A320neo-specific package, instruments, TypeScript systems, models, behaviors, and WASM.\n- `fbw-a380x/`: A380-specific package, instruments, TypeScript systems, and WASM.\n- `fbw-common/`: code shared by both aircraft, including SDK utilities, instrument components, typings, tests, and common WASM crates.\n- `fbw-ingamepanels-checklist-fix/`: separate in-game panel package.\n- `scripts/`: setup, build, packaging, lint, and development-container entry points.\n- `tools/`: standalone project utilities.\n- `large-files/`: Git submodule for large binary assets. Do not modify its contents or submodule pointer unless the task explicitly concerns those assets.\n- `igniter.config.mjs`: top-level build graph. `fbw-a32nx/mach.config.js` and `fbw-a380x/mach.config.js` register instrument entry points.\n- `fbw-*/out/`, `build/`, `target/`, instrument bundles, and generated localization files are build products; change their source or generator rather than generated output.\n\nPut aircraft-independent behavior in `fbw-common` when both aircraft genuinely share the same contract. Keep aircraft geometry, configuration, simvars, and system behavior in the relevant aircraft tree. Preserve existing path aliases such as `@flybywiresim/*`, `@shared/*`, and `@instruments/*` instead of adding long relative imports.\n\n## Generated sources\n\n- Do not modify generated behavior XML sources in `generated` folders.\n- Do not modify the generated `model/` folders in the fly-by-wire WASM modules: `fbw-a32nx/src/wasm/fbw_a320/src/model/` and `fbw-a380x/src/wasm/fbw_a380/src/model/`.\n\n## Environment and build system\n\nThe pinned Docker development environment is the source of truth for full builds and CI-equivalent validation. Initialize the submodule before building.\n\n```sh\ngit submodule update --init\n./scripts/dev-env/run.sh ./scripts/setup.sh\n./scripts/dev-env/run.sh ./scripts/build.sh\n```\n\nOn Windows, use `scripts\\dev-env\\run.cmd` in place of `run.sh`. Setup runs `pnpm install`; keep `pnpm-lock.yaml` synchronized and do not introduce another package manager lockfile.\n\n**Important:** Set `FBW_TYPECHECK=1` in the environment to enable TypeScript checks. This must be done before code is considered deliverable.\n\nUseful scoped commands:\n\n```sh\n# Full aircraft builds (the -r expression selects Igniter tasks)\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a32nx\"\n./scripts/dev-env/run.sh ./scripts/build.sh -r \"a380x\"\n\n# Instrument-only development, from the selected aircraft directory\npnpm exec mach build -f PFD\npnpm exec mach watch -f PFD\n\n# Or from the repository root\npnpm exec mach build --config fbw-a32nx/mach.config.js --work-in-config-dir -f PFD\n```\n\nMach/esbuild contains native binaries. If dependencies were installed inside the Linux container, host-side Mach can fail; run it in a matching environment or reinstall the host binary as described in the instrument README. Full builds also require the initialized `large-files` submodule. Avoid a full two-aircraft build when a focused instrument, crate, or test validates the change.\n\nThe Rust workspace is defined by the root `Cargo.toml`, pinned by `rust-toolchain.toml`, and targets `wasm32-wasip1`. C++/WASM code is built through the root CMake configuration and `scripts/build-cmake.sh`.\n\n## React versus FSComponent\n\nThis repository has two unrelated JSX runtimes. A `.tsx` suffix alone does not identify which one a file uses. Before editing or moving instrument code, inspect the instrument's nearest `tsconfig.json`, its entry point, and its registration in the aircraft `mach.config.js`.\n\n### MSFS SDK FSComponent instruments\n\nThe normal instrument tsconfig uses:\n\n```json\n\"jsxFactory\": \"FSComponent.buildComponent\",\n\"jsxFragmentFactory\": \"FSComponent.Fragment\"\n```\n\nMach registers these with `msfsAvionicsInstrument(...)`. Current examples include PFD, ND, EWD, FCU, Clock, MFD, OANC, and SDv2 (the exact lists differ by aircraft).\n\n- Use `DisplayComponent`, `FSComponent`, `VNode`, `Subject`/`MappedSubject`, event-bus publishers and subscribers, and SDK lifecycle methods.\n- Keep `FSComponent` imported when JSX needs the configured factory; ESLint intentionally exempts that name from unused-variable reporting.\n- Use FSComponent JSX conventions, notably `class`, subscribable attributes, and SDK refs. Do not mechanically convert them to React's `className` or React refs.\n- Create subscriptions in the appropriate lifecycle phase (usually `onAfterRender`). Retain subscriptions/resources and destroy them in `destroy()`, then call `super.destroy()`.\n- Mount with `FSComponent.render(...)` from the base instrument's `connectedCallback`; drive publishers/backplanes from the instrument update lifecycle.\n- Do not use React hooks, React context, `ReactDOM`, or React-only libraries in an FSComponent tree.\n\n### React instruments\n\nReact instruments extend `tsconfig.react.json`, whose JSX factory is `React.createElement`, and Mach registers them with `reactInstrument(...)`. Examples include EFB and BAT plus legacy or aircraft-specific instruments such as A32NX SD and A380X SD/RTPI.\n\n- Use React 17 conventions: `className`, React refs, hooks, context/providers, and the existing React render helper.\n- Use `@flybywiresim/fbw-sdk-react` hooks where established. Clean up timers, listeners, and subscriptions in the `useEffect` cleanup function.\n- Follow the Rules of Hooks even though the root ESLint configuration cannot yet enforce every React rule.\n- Do not pass React elements or hooks into an FSComponent subtree. Share framework-neutral data/model code when logic is needed by both runtimes.\n- New instruments should use FSComponent; the instrument README explicitly says to avoid React for new instruments unless the development team agrees otherwise.\n\nWhen adding an instrument, update the appropriate `mach.config.js`, choose the correct helper, add the matching local tsconfig inheritance, and follow a neighboring instrument's base-instrument registration and package layout.\n\n## TypeScript and JavaScript conventions\n\n- TypeScript is preferred in `src/systems`; JavaScript is mainly for build/config scripts and legacy exceptions.\n- The simulator runtime targets ES2017/Coherent GT. Do not assume Node.js APIs or modern browser APIs are available in shipped instrument code.\n- Use 2 spaces, single quotes, trailing commas where Prettier emits them, and a 120-column print width. Let repository ESLint/Prettier rules decide formatting.\n- The TypeScript strictness plugin is incremental. Do not add `// @ts-strict-ignore` to new files or broaden an existing exemption merely to silence errors; keep new and modified code strictly typed where practical.\n- Prefix intentionally unused parameters or locals with `_`. Do not add blanket ESLint disables when a narrow line-level exception is sufficient.\n- Preserve the copyright/SPDX header style used by neighboring files. When modifying a file with a copyright header, extend its ending year to the current calendar year; retain existing holders and SPDX identifiers.\n- Keep simulator reads/writes, event-bus topics, ARINC validity handling, units, and update frequency explicit. Avoid polling faster than the source data requires.\n- Follow local naming and file organization. Instrument folders contain domain-specific conventions that are more authoritative than distant examples.\n\n## Rust and C++ conventions\n\n- Format Rust with `cargo fmt`; keep Clippy warning-free under the flags in `scripts/lint-rust.sh`.\n- Add Rust unit tests close to the module under test. Use package-scoped commands during iteration, then workspace validation when warranted.\n- Follow the root `.clang-format` (Chromium base, two-space indentation, 140-column limit) or a closer subtree override for C/C++.\n- Preserve physical units and simulation update semantics. Prefer the existing typed-unit and simulation-element abstractions over raw numeric values.\n\n## Tests and validation\n\nRun the smallest relevant checks first, followed by the broader checks justified by the change.\n\n```sh\n# TypeScript/JavaScript\npnpm lint\npnpm test\npnpm exec vitest run path/to/file.spec.ts\n\n# Rust (CI-equivalent scripts)\n./scripts/dev-env/run.sh scripts/lint-rust.sh\n./scripts/dev-env/run.sh scripts/test-rust.sh\n\n# Faster scoped Rust iteration\ncargo test -p <package>\ncargo clippy -p <package> --all-targets --all-features -- -D warnings -A clippy::too_many_arguments -A deprecated\n```\n\nTypeScript tests are colocated as `*.spec.ts`/`*.spec.tsx`; Vitest uses `jsdom` and `fbw-common/src/jest/setupJestMock.ts`. Add regression tests for pure logic and system behavior where feasible. UI or simulator-coupled changes should also receive a focused Mach build and an in-simulator check when behavior cannot be covered outside MSFS. Report which checks ran and which could not run.\n\nBefore handing off a change:\n\n1. Review `git diff` and do not include build products, secrets, `.env` changes, or unrelated user modifications.\n2. Run lint/tests for touched languages and a focused build for affected instruments or aircraft.\n3. Keep `pnpm-lock.yaml` and `Cargo.lock` changes intentional.\n4. For contributions, follow `.github/Contributing.md`: realism changes need supporting documentation, commits/PR titles use Conventional Commits, and user-visible changes require an entry in `.github/CHANGELOG.md`.\n","category":"root","tokens":2371}]}