triage-tui 0.4.1

TUI to monitor parallel Claude Code and Codex CLI sessions across tmux panes — triage by attention priority
# Packaging & release

triage ships through three channels. The crate is named **`triage-tui`** on
crates.io (the name `triage` was taken); the installed **binary stays `triage`**
via the `[[bin]]` section in `Cargo.toml`.

## How a release happens

1. Land conventional-commit PRs on `main` (`feat:`, `fix:`, …).
2. [Release Please]https://github.com/googleapis/release-please keeps an open
   "Release PR" that bumps `Cargo.toml` + `CHANGELOG.md`. Merging it tags
   `vX.Y.Z` and cuts a GitHub Release.
3. That triggers the `publish` job in `.github/workflows/release.yml`, which:
   - builds a **universal macOS binary** + the notify `.app`, tars them, and
     attaches `triage-macos-universal.tar.gz` to the Release;
   - **publishes `triage-tui` to crates.io** (if a token/Trusted Publishing is set up);
   - **bumps the Homebrew tap** formula (if the tap token is set up).

## One-time setup (required before the first real release)

These are **human prerequisites** — the workflow steps that need them are
guarded (`if: env.… != ''`) so the pipeline stays green until they exist:

- **crates.io** — either configure [Trusted Publishing]https://crates.io/docs/trusted-publishing
  for the `triage-tui` crate (no secret needed; uses the workflow's `id-token`),
  **or** add a `CARGO_REGISTRY_TOKEN` repo secret. The crate name is reserved by
  the first successful publish — do an initial manual `cargo publish` if you want
  to claim `triage-tui` before automating.
- **Homebrew tap** — create the repo `inkless/homebrew-triage`, drop
  `packaging/homebrew/triage.rb` in it as `Formula/triage.rb`, and add a
  `HOMEBREW_TAP_TOKEN` repo secret (a PAT with `repo` scope on the tap). Then
  users install with `brew install inkless/triage/triage`.

## Validated vs. needs-validation

- **crates.io packaging**`cargo publish --dry-run` passes. build.rs writes
  the `.app` into `OUT_DIR` (not the source tree), so verification succeeds, and
  it still stages the helper to `~/.config/triage` so `cargo install triage-tui`
  produces a working binary with notifications.
-**Homebrew** — validated via a real `brew install inkless/triage/triage`:
  the formula builds the `triage-tui` crate from the crates.io source crate and
  installs the helper under `prefix/scripts/triage-notify/`, which triage's
  runtime probe resolves. The `release.yml` bump step refreshes the formula's
  url/version/sha256 from the new `.crate` on each release.

## Known gotchas ("what goes wrong")

- **Gatekeeper on prebuilt binaries** — the universal tarball is **not** Developer
  ID-signed or notarized, so a downloaded binary is quarantined. Users must
  `xattr -dr com.apple.quarantine triage triage-notify.app` (or right-click →
  Open) once. The Homebrew/`cargo install` paths build from source and avoid this.
- **`brew` build sandbox `$HOME`** — build.rs stages the helper to `$HOME` during
  build, but brew's build `$HOME` is a sandbox, not the user's. That's why the
  formula additionally installs the `.app` into the prefix (where the runtime
  probe finds it) rather than relying on the `$HOME` stage.
- **CI runs on `macos-latest`** — triage is macOS-targeted (swiftc in build.rs,
  tmux/ps joins). Linux CI would skip the helper and risk platform-specific test
  drift, so we test on the real target. macOS minutes cost more — acceptable for
  a solo project.
- **crates.io name ≠ tool name** — the crate is `triage-tui`; never reference
  `triage` as the crate name in install docs. `cargo install triage-tui`  `triage` binary.