fmtview 0.1.0

Fast terminal formatter and viewer for JSON, JSONL, XML, and formatted diffs
# Releasing

This document is for maintainers and agents preparing a public release.

Do not move this workflow into `README.md`. README should describe installation
methods that are already available to users. Release mechanics, unpublished
distribution plans, tokens, and maintainer checklists belong here.

## Distribution Channels

Current stable channel:

- Git install: `cargo install --git https://github.com/siriusctrl/fmtview --locked`

Target public channels:

- GitHub Releases with prebuilt binaries and checksums.
- crates.io, so Rust users can run `cargo install fmtview --locked`.
- npm, so Linux x64 users without a Rust toolchain can run `npm install -g fmtview`.

Add a channel to README only after it is actually published and verified.

## Version Policy

- Keep the Cargo package version as the source of truth.
- Use semver.
- Release tags should be `vX.Y.Z`.
- The tag version must match `Cargo.toml` exactly.
- Do not publish from arbitrary branch pushes or pull requests.

Recommended release sequence:

```sh
cargo fmt --check
cargo test
cargo clippy --all-targets -- -D warnings
cargo build --release
git status -sb
```

If registry secrets changed, run the manual `Release Auth Check` workflow before
tagging. That workflow verifies the npm token with `npm whoami`, checks that
the crates.io secret is configured, and runs a crates.io package dry-run. The
crates.io token itself is fully validated only by the real publish step because
Cargo dry-runs do not upload.

Then update `Cargo.toml`, commit, tag, and push:

```sh
git commit -am "chore: release vX.Y.Z"
git tag vX.Y.Z
git push origin main vX.Y.Z
```

## GitHub Actions Release Shape

Use a dedicated release workflow triggered by version tags:

```yaml
on:
  push:
    tags:
      - "v*"
```

The workflow should:

- Check out the tagged commit.
- Verify the tag version matches `Cargo.toml`.
- Verify the npm package version matches `Cargo.toml`.
- Run `cargo fmt --check`, `cargo test`, and `cargo clippy --all-targets -- -D warnings`.
- Build the Linux x64 release binary.
- Package the binary as `fmtview-linux-x64.tar.gz`.
- Generate `sha256sums.txt`.
- Create or update a GitHub Release for the tag.
- Upload the binary archive and checksums as release assets.
- Publish to crates.io if `CARGO_REGISTRY_TOKEN` is configured.
- Publish to npm if `NPM_TOKEN` is configured.

If either registry secret is missing, the workflow still builds the GitHub
Release artifact and skips that registry publish step.

Initial target:

- `x86_64-unknown-linux-gnu`

Potential future targets:

- `aarch64-unknown-linux-gnu`
- `x86_64-apple-darwin`
- `aarch64-apple-darwin`

## crates.io

Before the first crates.io publish, ensure `Cargo.toml` has complete package
metadata:

- `description`
- `license`
- `repository`
- `readme`
- `keywords`
- `categories`

Use `cargo publish --dry-run` before publishing.

Publish only from a release tag or an approved release workflow. The release
workflow uses the `CARGO_REGISTRY_TOKEN` GitHub secret when it is configured:

```sh
gh secret set CARGO_REGISTRY_TOKEN
```

After the first publish, README may list:

```sh
cargo install fmtview --locked
```

## npm

npm should be an installation wrapper for prebuilt Rust binaries, not a second
implementation.

Initial package layout:

- `fmtview` - JS shim plus a bundled Linux x64 binary.

The npm package exposes the CLI through `package.json` `bin`, and the shim
executes `vendor/fmtview`. It is intentionally Linux x64 only for the first
release.

A future multi-platform npm release should move to a root wrapper package plus
platform packages in `optionalDependencies`. Prefer that over downloading
binaries in `postinstall`; platform packages are easier to audit and behave
better in restricted CI environments.

When publishing to npm from GitHub Actions:

- Use `actions/setup-node` with the npm registry URL.
- Publish public packages with provenance.
- Grant `id-token: write` only to the npm publish job.
- Keep npm publish jobs tag-gated and never run them for pull requests.
- Configure the `NPM_TOKEN` GitHub secret:

```sh
gh secret set NPM_TOKEN
```

README may list npm installation only after the package has been published and
smoke-tested:

```sh
npm install -g fmtview
```

## Release Checklist

Before tagging:

- Version updated in `Cargo.toml`.
- `cargo fmt --check` passes.
- `cargo test` passes.
- `cargo clippy --all-targets -- -D warnings` passes.
- `cargo build --release` passes.
- TUI smoke test runs under a real PTY if viewer behavior changed.
- README lists only installation channels that already work.

After publishing:

- Install from the published channel and run `fmtview --version`.
- Open a JSON, JSONL, and XML sample in the viewer.
- Verify GitHub Release checksums.
- Verify crates.io or npm package pages point to the repository.

If a bad release is published:

- Prefer publishing a fixed patch release.
- Use `cargo yank` only for crates that should no longer be selected by new
  dependency resolution.
- Deprecate or unpublish npm packages only when the npm policy and timing allow
  it; otherwise publish a fixed version.