nyx/scripts/README.md

101 lines
4.3 KiB
Markdown

# scripts
Local helpers for repo-wide checks and a couple of one-off tools.
| Script | What it does |
| ------------------------ | --------------------------------------------------------------------------------------------- |
| `fix.sh` | Apply all auto-fixes (clippy, fmt, eslint, prettier), then run tests. |
| `check.sh` | Verify only (no fixes). Mirrors the GitHub Actions CI workflow. |
| `cached-cargo-test.sh` | Wrap `cargo test` with a source-hash cache; concurrent invocations of the same args share one run. |
| `capture-screenshots.mjs`| Capture the README stills and demo GIF from a running `nyx serve`. Needs Playwright and ffmpeg. |
| `frame-screenshots.py` | Wrap a PNG in the brand mint-cyan gradient. Called by `capture-screenshots.mjs` as its final phase, but can be run standalone. |
Fixers stream their output (so you can see what changed); tests run quietly and
only show output if they fail. Both scripts print a green/red summary at the end
and exit non-zero if any step failed.
## Usage
```bash
./scripts/fix.sh # fix everything + run tests
./scripts/fix.sh --no-tests # just apply fixes
./scripts/fix.sh --rust-only # skip frontend
./scripts/fix.sh --frontend-only
./scripts/check.sh # verify everything (CI-equivalent)
./scripts/check.sh --rust-only
```
Scripts can be run from any directory; they resolve the repo root from their
own location.
## Cached cargo test
Wraps `cargo test`. The first run executes normally and records its output
keyed by a hash of the source tree. Later runs with the same args and an
unchanged tree return the cached output. Concurrent callers share a single
cargo run via a mkdir lock.
```bash
./scripts/cached-cargo-test.sh --lib
./scripts/cached-cargo-test.sh --tests
FORCE_CARGO=1 ./scripts/cached-cargo-test.sh --lib # bypass cache
```
Use it for full-suite invocations. Narrow per-test runs (`cargo test
some_function`) are fast on their own and just clutter the cache.
## Capture screenshots
Regenerates `assets/screenshots/*.png` and `assets/screenshots/demo.gif` for
the README and `docs/`. Requires Playwright, ffmpeg, and Python 3 with
Pillow on PATH, plus a running `nyx serve` on `$NYX_URL` (default
`http://127.0.0.1:9876`). The served scan root must have no prior scans.
```bash
node scripts/capture-screenshots.mjs --stills # only PNGs
node scripts/capture-screenshots.mjs --gif # only the GIF
node scripts/capture-screenshots.mjs --all # both
```
The script writes a synthetic demo to `$SCAN_ROOT` (default
`/tmp/nyx-demo-app`). V1 has four endpoints and produces a 5-hop CMDi
taint flow that the GIF drills into. After scan #1 the script overwrites
the demo with V2 (just that one flow) and runs scan #2 via the API, so
the overview trend chart shows findings going down.
Stills are captured in two phases:
- After scan #1 (more findings): `serve-findings-list.png`,
`serve-finding-detail.png`.
- After scan #2 (trend established): `serve-overview.png`,
`serve-triage.png`, `serve-explorer.png`, `serve-scans.png`,
`serve-scan-detail.png`, `serve-rules.png`, `serve-config.png`.
Then `frame-screenshots.py` runs over every captured PNG and wraps it in
the brand mint-led four-corner gradient (1800x1113 outer, 1600x992 inner,
12px rounded corners: TL `#72f3d7`, TR `#ff6aa2`, BL `#f8c56b`, BR
`#4cc9ff`). Finally,
`docs/serve-overview.png` is copied to the top-level `overview.png`
because that is the path the README references.
GIF storyboard:
1. Empty dashboard with the "Run your first scan" prompt.
2. Click `Start Scan` in the header bar to open the modal.
3. Confirm in the modal and wait for the scan to finish.
4. Back to the overview, scroll down through the cards, scroll back.
5. Click `Findings` in the sidebar.
6. Click the 5-hop taint row.
7. On the finding detail, expand Evidence, Analysis Notes, and
Confidence Reasoning.
8. Open the triage status dropdown and dismiss it.
9. Navigate to `/debug/call-graph` for the closing visual.
To frame an existing PNG without re-capturing:
```bash
python3 scripts/frame-screenshots.py path/to/foo.png [...]
```
Run with no args to re-frame every PNG under `assets/screenshots/`.