# Local development setup

This source is `oxcgen@0.2.0`. It is not a certified compiler. Nothing in this
bundle claims access to the user's Mac. See [VALIDATION_STATUS.md](VALIDATION_STATUS.md)
for executed checks and limits.

## Prepare the source repository

Use the current source checkout, including `package-lock.json` and `vendor/`.
An older source ZIP or self-contained installer is not evidence that it contains
the current dependency corrections. Do not extract an older bundle over an
existing checkout.

## Bootstrap an already extracted source repository

```bash
cd ~/projects/oxcgen
bash scripts/bootstrap-local.sh
```

The bootstrap uses Node **24.20.0**, pinned in `.node-version` and `.nvmrc`.
When that exact runtime is not active, it downloads the official platform archive
from `nodejs.org` and verifies its SHA-256 against that release's HTTPS checksum
manifest. This is integrity verification, NOT a separate GPG-signature check.
The private runtime and npm cache live under `.oxcgen/`, which is Git-ignored and
excluded from candidate snapshots. Other projects' Node versions do not change.

The runtime must still work on the host platform. Unsupported systems or failed
downloads stop setup. The supported private runtime paths are macOS/Linux on
arm64 and x64. This is not a claim that all four platforms have been tested.

The checked-in `package-lock.json` owns dependency resolution. Bootstrap uses
`npm ci`, including optional native packages and development dependencies such as
Blume. Only a source tree without a lock triggers bootstrap's initial lock
resolution; routine installation must not regenerate the supplied lock.

The Pi development dependency is a local `file:vendor/...tgz` artifact, with its
corrected AI dependency bundled inside. Keep `vendor/` alongside the manifest and
lock when copying source. [vendor/README.md](vendor/README.md) owns the artifact
provenance and reproduction procedure; no installed-cache patch or disabled
declaration checking is needed. After selecting the runtime, `./dev npm ci`
reinstalls dependencies without running the full bootstrap validation sequence.
Normal npm lifecycle scripts can run during installation: this is a trusted-project
install, not a hostile-code sandbox.

Setup then runs the source release gate, packages the actual artifact, installs
that artifact into a disposable consumer, and runs native integration tests
against the installed package. It retains failures and exits 2 when blocked or
when automated release checks fail. No tests are weakened to make setup pass.

## Use the selected runtime

Select the command for the work being checked. `validate:release` already runs
`check`, `test:local`, and `test:integration`; do not run them again as its
preflight. Bootstrap also invokes that release runner before testing the packed
consumer, so it replaces a separate release invocation when installation is needed.

```bash
./dev npm run check
./dev npm run test:local
./dev npm run test:integration
./dev npm run validate:release
./dev npm run docs:dev
```

`./dev` changes only that process's runtime environment. Source `.oxcgen/env.sh`
explicitly to use the selection in the current Bash/Zsh shell, if needed.
`./dev node scripts/setup-local.mts --preflight` records tool availability without
installing packages. `--validate-only` checks an existing dependency installation.

## Isolated Linux validation

`bash validation/docker.sh` runs the release gates and an installed-consumer
check inside a read-only container limited to 2 CPUs, 256 PIDs and 6 GiB, the
measured runtime envelope. A cold build of the patched Oxlint binding peaks at
about 3.5 GiB of resident memory, inside that envelope, but the limit only
holds if Docker Desktop's VM has more memory than the container (8 GB is a safe
setting; a 4 GB VM kills the compiler regardless of the container limit). The
container's `/tmp` and `/workspace` volumes, the base images and the caches all
consume the Docker host's disk; CI frees unused preinstalled toolchains first.
`OXCGEN_DOCKER_CACHE=<dir>` bind-mounts the caches from a host directory instead
of named volumes; the Go build cache lives there too.

## Release

A push to `master` releases. `.github/workflows/release.yml` reads `version`
from `package.json`, does nothing when npm already has `oxcgen@<version>`, and
otherwise builds the native hosts for `linux-x64`, `linux-arm64` and
`darwin-arm64` on GitHub-hosted runners, packs the platform packages and
`oxcgen`, and publishes them, platform packages first (a prerelease version
gets the `next` dist-tag, any other `latest`). Bumping `version` and pushing is
the whole release; a rerun after a partial failure publishes only the packages
npm is missing. Publishing authenticates with the `NPM_TOKEN` repository
secret or npm trusted publishing.

The checkout never declares the platform packages: their versions exist only
once published, so the lockfile could not resolve them. Every packing path
(the workflow's pack job, the isolated validation lane and the local setup)
runs `scripts/release-version.mts` before `npm pack`, declaring one optional
platform package per build receipt in `native/bin`. The runtime prefers a
locally built `native/bin` over an installed platform package.

`gh workflow run release.yml -f version=<semver> -f platforms=<list> -f publish=<bool> -f tag=<dist-tag>`
runs the same pipeline by hand, for a dry run (`publish=false` packs and
uploads the tarballs only) or for `darwin-x64`, which pushes never build because
its `macos-15-intel` runner bills at the macOS multiplier on a private
repository. The isolated validation lane also packs a platform tarball for the
runner's own platform under `.validation-evidence/platforms/`.

## Evidence and interpretation

Run logs live under `.oxcgen/local-runs/<timestamp>-<id>/`. The full path to the
most recent run is in `.oxcgen/LAST_LOCAL_RUN`. Its `summary.json` separates
installation completion from passing automated release checks. Neither is a
claim of complete native implementation, browser tests, or production readiness.

Current remaining work and limits are itemized in `OXCGEN_REMAINING_WORK.md`.
Historical prompts, audits and reports live under `reports/history/`; they are
not current remaining-work authority. Consult the latest logs for the
complete release result.

## Development mode versus consumer mode

This repository uses `mode: "advisory"` so its unfinished generator does not block
its own implementation. Strict lint/type settings and release gates remain intact.
`oxcgen init` uses separate consumer templates with `mode: "required"`; it does not
copy the development exception or developer-specific AGENTS.md into applications.
The Pi extension routes its managed `edit`/`write` operations according to that
mode. Shell, MCP and unrelated writers are not covered by those overrides;
`runRestrictedAgent` is the separate explicitly launched OS-restricted host.

## TypeScript implementation

Authored `.js` files have been converted to `.ts`, and `.mjs` to `.mts`. Oxc emits
`lib/` for normal package installation; native type checking remains in Go.

## Blume

Use the existing Blume project; do not scaffold over it or introduce a second docs
framework. The setup runs real `blume check`, `validate`, `build`, and `audit`, plus
a static output smoke test, through the release runner. Browser navigation,
keyboard search, mobile behavior and runtime errors must additionally be tested
against actual built output. Do not start a dev server concurrently with plain
build/check commands; use Blume's documented isolation controls when appropriate.

## Upstream references

- Node release/download: https://nodejs.org/en/download
- Oxlint TypeScript runtime: https://oxc.rs/docs/guide/usage/linter/config.html
- Lockfile installation: https://docs.npmjs.com/cli/v11/commands/npm-ci/
- Blume setup: https://useblume.dev/docs/quickstart
- Blume verification: https://useblume.dev/docs/reference/cli
