mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
f199640bdc
- Switch font: JetBrains Mono @ 15px → Unifont 16.0.04 @ 10px. Sparse atlas with double-width EAW dispatch for CJK. Full BMP profile (35,501 glyphs) covers Latin/Cyrillic/Greek/Hebrew/Arabic/CJK/Hangul plus Letterlike, Misc Technical, Block Elements, Geometric Shapes, Misc Symbols, Dingbats, Enclosed Alphanumerics, all box-drawing. - Fix cell-height bug (was hardcoded 9; now probed from font metrics via Math.ceil(maxAscent+maxDescent)). Previously clipped the top 2 rows off every CJK glyph since the original Unifont ship. - Expand tabs to spaces with 4-column tab stops, EAW-aware. Was the silent-drop source for 99.6% of dropped chars in production. - Add dropped_codepoints_top telemetry (top 20 per event, only emitted when drops > 0) so future coverage gaps surface in events.jsonl. - Raise minToolResultChars 2000→5000 and minReminderChars 1000→2000 to stop net-losing tokens on small compressions, per ~2,500 tok/img empirical measurement (N=33 cold-miss events). - Fix dashboard per-image-cost formula: was pngBytes/375 (~190 tok), now imageCount * 2500 (the measured empirical rate). Reduces the inflated "tokens saved" headline to honest numbers. - Schema-stub fix in compressSchemas path: preserveSchemaShell() retains type / properties / required / enum / oneOf / anyOf / $ref / numeric constraints recursively (depth 20), strips only descriptions and metadata. Prevents 400 errors on first-tool-call requests. - Capture full gzipped 4xx body + per-event req_body_sha8 for upstream error diagnosis. Sidecar to ~/.pixelpipe/4xx-bodies/ when over 32 KB inline cap. Workers-safe via CompressionStream + Web Crypto. - scripts/restart.sh: pnpm-aware one-command kill+rebuild+start with graceful SIGTERM→SIGKILL escalation, build-failure abort, port-in-use precheck, --no-build flag for fast iteration. Shell-tested. - Bundle 1.58 MB gzipped on Node. 91/91 vitest + 4/4 shell tests.
128 lines
4.4 KiB
Bash
Executable File
128 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Restart the local pixelpipe proxy.
|
|
#
|
|
# What this does, in order:
|
|
# 1. Discover every running pixelpipe proxy via `pgrep -f "node.*bin/cli.js"`
|
|
# and list them. If multiple are running (orphans from a prior crashed
|
|
# session), kill all of them — there's no "right" oldest in a graceful
|
|
# restart, we want a clean slate.
|
|
# 2. Send SIGTERM. The proxy's SIGTERM handler flushes the JSONL tracker
|
|
# and exits. Poll up to 5s for clean exit.
|
|
# 3. Anything still alive after 5s gets SIGKILL with a warning.
|
|
# 4. Rebuild (`pnpm run build`) unless --no-build is passed. Build errors
|
|
# abort the restart so we never start a stale binary.
|
|
# 5. Check the target port is actually free; if not, name the process
|
|
# holding it (with a hint for the user — common cause: another tool, or
|
|
# step 3 didn't fully release).
|
|
# 6. Start a fresh proxy via `exec node bin/cli.js "$@"` so Ctrl-C reaches
|
|
# Node directly.
|
|
#
|
|
# Flags:
|
|
# --no-build Skip the rebuild step. Use when you know dist/ is fresh.
|
|
# Anything else (port, upstream, etc.) is passed through to
|
|
# the proxy unchanged.
|
|
#
|
|
# Examples:
|
|
# pnpm run restart
|
|
# pnpm run restart -- --no-build
|
|
# pnpm run restart -- --port 47899 --no-tools
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# --- Parse our own flags out of "$@". Everything else passes through. ----
|
|
DO_BUILD=1
|
|
PROXY_ARGS=()
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-build)
|
|
DO_BUILD=0
|
|
;;
|
|
*)
|
|
PROXY_ARGS+=("$arg")
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# --- Figure out which port the new proxy will bind. Default 47821; if the
|
|
# --- user passed --port we honor it. (We don't try to parse PORT= env var
|
|
# --- because that's handled inside bin/cli.js itself.)
|
|
TARGET_PORT=47821
|
|
prev=""
|
|
for arg in "${PROXY_ARGS[@]+"${PROXY_ARGS[@]}"}"; do
|
|
case "$prev" in
|
|
-p|--port)
|
|
TARGET_PORT="$arg"
|
|
;;
|
|
esac
|
|
prev="$arg"
|
|
done
|
|
|
|
# --- 1. Discover running proxies ------------------------------------------
|
|
# `[c]li.js` keeps pgrep from matching itself if anyone pipes us through grep.
|
|
PIDS_RAW=$(pgrep -f 'node.*bin/[c]li\.js' 2>/dev/null || true)
|
|
if [ -n "$PIDS_RAW" ]; then
|
|
# Convert to space-separated list, sorted numerically for stable output.
|
|
PIDS=$(echo "$PIDS_RAW" | tr '\n' ' ' | xargs -n1 | sort -n | tr '\n' ' ')
|
|
echo "[restart] found running pixelpipe proxy PID(s): $PIDS"
|
|
|
|
# --- 2. SIGTERM all of them ---
|
|
for pid in $PIDS; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
echo "[restart] SIGTERM $pid (graceful — tracker flushes on shutdown)"
|
|
kill -TERM "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
|
|
# Poll up to 5s for graceful exit.
|
|
for _ in $(seq 1 50); do
|
|
STILL=$(pgrep -f 'node.*bin/[c]li\.js' 2>/dev/null || true)
|
|
[ -z "$STILL" ] && break
|
|
sleep 0.1
|
|
done
|
|
|
|
# --- 3. Escalate to SIGKILL only if still alive ---
|
|
STILL=$(pgrep -f 'node.*bin/[c]li\.js' 2>/dev/null || true)
|
|
if [ -n "$STILL" ]; then
|
|
echo "[restart] WARNING: PID(s) still alive after 5s, escalating to SIGKILL: $STILL"
|
|
for pid in $STILL; do
|
|
kill -KILL "$pid" 2>/dev/null || true
|
|
done
|
|
sleep 0.3
|
|
fi
|
|
else
|
|
echo "[restart] no running proxy found"
|
|
fi
|
|
|
|
# --- 4. Rebuild (skippable) ----------------------------------------------
|
|
if [ "$DO_BUILD" -eq 1 ]; then
|
|
echo "[restart] rebuilding…"
|
|
if ! pnpm run build; then
|
|
echo "[restart] ERROR: build failed. Not starting a stale binary." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "[restart] --no-build: skipping rebuild (assuming dist/ is fresh)"
|
|
fi
|
|
|
|
# --- 5. Sanity-check the target port is free -----------------------------
|
|
# `lsof` is preinstalled on macOS and most Linux distros. If it isn't, we
|
|
# skip the check rather than failing — the new proxy will surface the same
|
|
# EADDRINUSE error via Node's listen() callback.
|
|
if command -v lsof >/dev/null 2>&1; then
|
|
HOLDER=$(lsof -nP -iTCP:"$TARGET_PORT" -sTCP:LISTEN -t 2>/dev/null || true)
|
|
if [ -n "$HOLDER" ]; then
|
|
HOLDER_CMD=$(ps -o command= -p "$HOLDER" 2>/dev/null || echo "?")
|
|
echo "[restart] ERROR: port $TARGET_PORT is still held by PID $HOLDER:" >&2
|
|
echo " $HOLDER_CMD" >&2
|
|
echo " Hint: if that's a pixelpipe proxy our SIGTERM should have cleared," >&2
|
|
echo " it may have been started outside this repo. Free the port and rerun." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# --- 6. Start fresh in the foreground. exec so Ctrl-C goes straight to Node.
|
|
echo "[restart] starting fresh proxy on :$TARGET_PORT (Ctrl-C to stop)"
|
|
exec node bin/cli.js "${PROXY_ARGS[@]+"${PROXY_ARGS[@]}"}"
|