Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing

Thanks for your interest in the project. This document covers the local setup and the checks your
change needs to pass.

## Prerequisites

- Go (see the version in [`go.mod`](go.mod))
- Node.js 24+ and npm
- `golangci-lint` and `shellcheck` on your `PATH`
- `air` and `lefthook` are pinned as Go tools and run via `go tool`; no separate install needed.

## Setup

```sh
go mod download
make hooks        # install the git hooks (lefthook)
cd web && npm i
```

## Day-to-day

```sh
make watch        # Vite dev server + Go backend (Air live-reload) behind a proxy
make generate     # regenerate the OpenAPI spec and the typed TS client after API changes
```

The TypeScript API client under `web/src/lib/api/` is generated. Never edit it by hand; change the
Go handlers and run `make generate`.

## Checks

Run these before pushing; the git hooks and CI run the same.

```sh
make lint         # golangci-lint, ESLint, svelte-check, shellcheck
make test         # go vet, Go tests with the coverage gate, then Vitest
make test-e2e     # Playwright (chromium locally; the full matrix runs in CI)
```

- **Coverage gate:** Go tests for `internal/` must stay above the threshold in the
  [`Makefile`](Makefile). Hardware adapter packages (`.../adapter`) are integration-tested on the
  device and excluded.
- **Frontend:** `npm run check` must report zero warnings.

## Mutation testing

[Stryker](https://stryker-mutator.io/) (frontend) and [Gremlins](https://gremlins.dev/) (Go, pinned
as a `go tool`) check that tests assert behaviour, not just run it. Run `make mutation` on demand;
it's deliberately out of the git hooks (too slow per push). A surviving mutant is a weak/missing
assertion (fix the test), a real bug (fix the code), or a true equivalent (leave it). Config:
`web/stryker*.json` and the `mutation` target in the [`Makefile`](Makefile).

CI runs mutation testing on every PR and push to main, scoped to the diff (Stryker
`--incremental` anchored to the main baseline, gremlins `--diff`). It is informational.
A red mutation check flags weak tests but does not block merging.

## Security

`make vuln` scans for known CVEs: govulncheck (Go, reachability-aware) and osv-scanner
over the bundle-truth CycloneDX SBOM the UI build emits (SvelteKit devDependencies are
the *bundled* deps, and package.json sections don't reflect what ships). The same scan
gates CI and runs daily (`security.yml`), which also `npm audit`s the full tree for
build-toolchain hygiene. Releases attach both SBOMs (frontend bundle + linked Go
modules) for downstream scanning. Dependabot opens security PRs that auto-merge on
green; weekly grouped version-update PRs wait for a human.

A transitive CVE with no upstream fix gets a scoped npm `overrides` entry naming the
package we are working around; drop it once that package asks for a safe version itself.

## Code style

Read [`STYLE.md`](STYLE.md). Match the surrounding code, keep comments to the non-obvious why, and
let the linters guide you rather than suppressing them. Reach for `nolint` / `eslint-disable` only
as a genuine last resort, with a reason.

## Commits

Conventional Commits, matching the existing history: `type(scope): summary`
(e.g. `refactor(wifi): split manager into command, profile, and policy files`).
Common types here: `feat`, `fix`, `refactor`, `test`, `chore`, `docs`.

## Releases & versioning

Strict [SemVer](https://semver.org). The in-app self-updater is on by default and
auto-applies any newer release **sharing the current major**, so a minor or patch
release MUST be backward-compatible. **Never ship a breaking change in a minor or
patch.** Anything that breaks config, the HTTP/MQTT contract, or on-disk state is a
**major**, which the updater surfaces but only applies on explicit confirmation.
When in doubt, bump the major.