diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9ed2250..57d72ec 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -18,6 +18,6 @@ - [ ] User-facing change → an entry under `## [Unreleased]` in `CHANGELOG.md` (without one, the merge releases nothing) - [ ] No network request, third-party resource, `innerHTML`, or dependency that needs `eval` - [ ] Anything touching a secret declares `store: { kind: 'none' }`; nothing multi-MB goes to `localStorage` -- [ ] Entry bundle still under ~90 kB gzip (CI enforces 92160 B) +- [ ] First-load JS still under 105 KiB gzip (CI enforces 107520 B) - [ ] Works at phone width: panes stack, 44px touch targets, no hover-only controls - [ ] Markdown prose is not hard-wrapped diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eccc450..554a576 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,17 +72,27 @@ jobs: exit 1 fi - # The entry bundle is what every visitor pays for on first load. If a - # heavy dependency escapes a lazy route chunk, this is where we find out - # rather than in production. - - name: Check entry bundle budget + # First-load JS is what every visitor pays for before any tool runs: the + # entry plus every chunk the HTML modulepreloads (the registry sits in + # one) and registerSW.js. If a heavy dependency escapes a lazy route + # chunk, this is where we find out rather than in production. + - name: Check first-load JS budget run: | - BUDGET=92160 - ENTRY=$(find dist/assets -name 'index-*.js' -print -quit) - SIZE=$(gzip -c "$ENTRY" | wc -c | tr -d ' ') - echo "entry: $ENTRY" - echo "gzipped: ${SIZE}B budget: ${BUDGET}B" - if [ "$SIZE" -gt "$BUDGET" ]; then - echo "::error::Entry bundle ${SIZE}B exceeds the ${BUDGET}B budget." + BUDGET=107520 + LIST="$RUNNER_TEMP/first-load.txt" + grep -oE '(src|href)="/[^"]+\.js"' dist/index.html | sed -E 's/^(src|href)="\///; s/"$//' > "$LIST" || true + if ! grep -qE '^assets/index-[^/]+\.js$' "$LIST"; then + echo "::error::No entry script found in dist/index.html." + exit 1 + fi + TOTAL=0 + while read -r FILE; do + SIZE=$(gzip -c "dist/$FILE" | wc -c | tr -d ' ') + echo "${SIZE}B $FILE" + TOTAL=$((TOTAL + SIZE)) + done < "$LIST" + echo "first-load JS, gzipped: ${TOTAL}B budget: ${BUDGET}B" + if [ "$TOTAL" -gt "$BUDGET" ]; then + echo "::error::First-load JS ${TOTAL}B exceeds the ${BUDGET}B budget." exit 1 fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 11b7bf4..5b2dca3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and ## [Unreleased] -Nothing yet. +### Added +- JSON Formatter: formatted output has line numbers and a fold gutter on desktop, so any object or array can be collapsed and expanded the way an editor does it, with Fold all (every level below the root) and Unfold all. Inputs over 1 MB and small screens keep the plain text view; on a phone, the Tree view folds. +- JSON Formatter: Generate types opens the current output (filtered, expanded and sorted as shown) in JSON to Types. Valid NDJSON can be sent straight from its banner, one sample per line. + +### Changed +- Diff: Sorted lines and Key-sorted JSON are built in the background, so turning them on for a large file no longer freezes the page. While a view is being built the previous one stays on screen (or a short busy message), Copy patch waits for it, and Cancel appears after 2 seconds. +- Base64, URL Encode / Decode and String Escaper stop soft-wrapping a line longer than 100,000 characters, so a multi-MB single line stays editable instead of taking seconds per keystroke. +- JSON Formatter and YAML / JSON / TOML show parse errors in the same card as JSON to Types; the JSON card no longer shows the character offset. + +### Fixed +- Diff: a share link pasted into the address bar of a Diff tab that is already open now loads without a reload. +- Diff: a large file with classic Mac line endings (a lone carriage return) is measured line by line instead of being refused as one long line. ## [0.13.0] — 2026-10-30 diff --git a/CLAUDE.md b/CLAUDE.md index b182b75..1a79c7a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -79,7 +79,7 @@ Load-bearing rules from it: - **A plain `