#!/usr/bin/env bash # check-browser-parity.sh — Verify Chrome/Firefox extension parity for all providers. # # Compares all source files between Firefox (-exporter-extension) and Chrome # (-exporter-chrome) variants. The only allowed difference is the # browser_specific_settings.gecko block in manifest.json. # # Usage: scripts/check-browser-parity.sh set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" EXT_ROOT="$REPO_ROOT/browser-extensions/history-extensions" PROVIDERS=(gemini copilot deepseek grok perplexity poe) # Files that must be byte-identical between variants. PARITY_FILES=( src/content/content.js src/lib/export.js src/lib/popup-core.js src/lib/popup-utils.js src/popup/popup.js src/popup/popup.html src/popup/popup.css src/popup/permissions.html ) log() { printf '[parity] %s\n' "$*" } err() { printf '[parity] FAIL: %s\n' "$*" >&2 } failures=0 checks=0 for provider in "${PROVIDERS[@]}"; do firefox_dir="$EXT_ROOT/${provider}-exporter-extension" chrome_dir="$EXT_ROOT/${provider}-exporter-chrome" if [[ ! -d "$firefox_dir" ]]; then err "$provider — Firefox directory missing: $firefox_dir" failures=$((failures + 1)) continue fi if [[ ! -d "$chrome_dir" ]]; then err "$provider — Chrome directory missing: $chrome_dir" failures=$((failures + 1)) continue fi for file in "${PARITY_FILES[@]}"; do checks=$((checks + 1)) ff_path="$firefox_dir/$file" cr_path="$chrome_dir/$file" if [[ ! -f "$ff_path" ]]; then err "$provider — Firefox missing: $file" failures=$((failures + 1)) continue fi if [[ ! -f "$cr_path" ]]; then err "$provider — Chrome missing: $file" failures=$((failures + 1)) continue fi if ! diff -q "$ff_path" "$cr_path" >/dev/null 2>&1; then err "$provider — $file differs between Firefox and Chrome" failures=$((failures + 1)) fi done # Validate manifest.json: only browser_specific_settings.gecko should differ. checks=$((checks + 1)) ff_manifest="$firefox_dir/manifest.json" cr_manifest="$chrome_dir/manifest.json" if [[ ! -f "$ff_manifest" || ! -f "$cr_manifest" ]]; then err "$provider — manifest.json missing from one or both variants" failures=$((failures + 1)) continue fi # Strip browser_specific_settings block from Firefox manifest and normalize # trailing commas so the remaining JSON structure matches Chrome. ff_stripped=$(sed '/"browser_specific_settings"/,/^ }/d' "$ff_manifest" | sed '/^$/d' | sed 's/,$//') cr_stripped=$(sed '/^$/d' "$cr_manifest" | sed 's/,$//') if ! diff -q <(echo "$ff_stripped") <(echo "$cr_stripped") >/dev/null 2>&1; then err "$provider — manifest.json has unexpected differences beyond browser_specific_settings" failures=$((failures + 1)) fi done echo "" passed=$((checks - failures)) log "Results: ${passed} passed, ${failures} failed (${checks} checks across ${#PROVIDERS[@]} providers)" if [[ "$failures" -gt 0 ]]; then err "Browser parity check failed." exit 1 fi log "All browser parity checks passed." exit 0