mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-10 13:31:38 +00:00
Ports the engine off the second JS runtime onto Node 26.3 (node:ffi) so the repo ships a single JavaScript runtime: child_process for the gateway, vitest for tests, an esbuild + Solid build step. Mouse selection copies the rendered text you highlight, and the clipboard path is crash-proofed (a broken copy pipe no longer quits the UI). Renames the engine dir ui-tui-opentui-v2/ -> ui-opentui/ and updates the launcher/installer/Docker references.
75 lines
3.9 KiB
Bash
75 lines
3.9 KiB
Bash
#!/usr/bin/env bash
|
|
# Single acceptance command for the Bun→Node-26 switchover (see
|
|
# docs/plans/opentui-node26-build-spec.md). Proves, on a Node 26.3 host, that the
|
|
# OpenTUI v2 engine runs WITHOUT Bun and at parity:
|
|
#
|
|
# 1. Node >= 26.3 present (the node:ffi floor); reports whether bun is on PATH
|
|
# (the engine must NOT need it).
|
|
# 2. `npm run check` — prettier + tsc + eslint + vitest (151+), all on Node.
|
|
# 3. live-gateway transport smoke — spawns the real Python tui_gateway via the
|
|
# node:child_process client, asserts gateway.ready + session.create.
|
|
# (Skipped if no Hermes venv resolves — CI parity.)
|
|
# 4. selection/markdown smoke in a real tmux TTY — asserts the native <markdown>
|
|
# (Tree-sitter) PAINTS under node --experimental-ffi and that a selection
|
|
# copies the RAW markdown source. (Skipped if tmux is unavailable.)
|
|
#
|
|
# Run: cd ui-opentui && HERMES_PYTHON_SRC_ROOT=<checkout-root> bash scripts/acceptance.sh
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# Absolute node, so a fresh tmux pane (which won't inherit our PATH / fnm shim)
|
|
# runs the SAME Node 26.3, not the shell's default.
|
|
NODE_BIN="$(command -v node || echo node)"
|
|
|
|
pass=0; fail=0; skip=0
|
|
ok() { echo " ✅ $1"; pass=$((pass+1)); }
|
|
bad() { echo " ❌ $1"; fail=$((fail+1)); }
|
|
note() { echo " ⏭ $1"; skip=$((skip+1)); }
|
|
|
|
echo "== [1/4] runtime: Node >= 26.3, Bun-free =="
|
|
NODE_V="$(node -p 'process.versions.node' 2>/dev/null || echo 0.0.0)"
|
|
node -e 'const [a,b]=process.versions.node.split(".").map(Number); process.exit(a>26||(a===26&&b>=3)?0:1)' \
|
|
&& ok "node $NODE_V (>= 26.3)" || bad "node $NODE_V is below the 26.3 node:ffi floor"
|
|
if command -v bun >/dev/null 2>&1; then
|
|
note "bun is on PATH ($(command -v bun)) — fine; the engine does not use it (proven below)"
|
|
else
|
|
ok "no bun on PATH — single-runtime host"
|
|
fi
|
|
|
|
echo "== [2/4] check: prettier + tsc + eslint + vitest =="
|
|
if bash scripts/check.sh >/tmp/accept-check.log 2>&1; then ok "check green ($(grep -c 'passed' /tmp/accept-check.log >/dev/null 2>&1; grep -oE '[0-9]+ passed' /tmp/accept-check.log | tail -1))"
|
|
else bad "check failed — see /tmp/accept-check.log"; tail -20 /tmp/accept-check.log; fi
|
|
|
|
echo "== [3/4] live-gateway transport smoke (real Python gateway, no Bun) =="
|
|
if [ -n "${HERMES_PYTHON_SRC_ROOT:-}" ] || [ -x "../.venv/bin/python" ]; then
|
|
rm -rf .accept && node scripts/build.mjs src/test/liveGateway.smoke.ts .accept >/dev/null 2>&1
|
|
OUT="$(node --experimental-ffi --no-warnings .accept/liveGateway.smoke.js 2>&1)"
|
|
echo "$OUT" | grep -q "^PASS" && ok "$(echo "$OUT" | grep '^PASS')" || { echo "$OUT" | grep -qE "TRANSPORT ERROR|SKIP" && note "gateway smoke skipped (no python/model)" || bad "gateway smoke: $(echo "$OUT" | head -1)"; }
|
|
rm -rf .accept
|
|
else
|
|
note "no HERMES_PYTHON_SRC_ROOT / venv — gateway smoke skipped"
|
|
fi
|
|
|
|
echo "== [4/4] selection/markdown smoke in a real tmux TTY (tree-sitter under FFI) =="
|
|
if command -v tmux >/dev/null 2>&1; then
|
|
rm -rf .accept && node scripts/build.mjs src/test/selectionCopy.smoke.tsx .accept >/dev/null 2>&1
|
|
rm -f /tmp/accept-sel.json
|
|
S="accept-$$"
|
|
tmux kill-session -t "$S" 2>/dev/null
|
|
tmux new-session -d -s "$S" -x 120 -y 40
|
|
tmux send-keys -t "$S" "SEL_SMOKE_OUT=/tmp/accept-sel.json $NODE_BIN --experimental-ffi --no-warnings $PWD/.accept/selectionCopy.smoke.js; tmux wait-for -S $S" Enter
|
|
tmux wait-for "$S" 2>/dev/null || sleep 6
|
|
tmux kill-session -t "$S" 2>/dev/null
|
|
if node -e 'process.exit(require("/tmp/accept-sel.json").pass===true?0:1)' 2>/dev/null; then
|
|
ok "markdown painted + selection copied source (tree-sitter under node FFI)"
|
|
else
|
|
bad "selection/markdown smoke failed — see /tmp/accept-sel.json"; cat /tmp/accept-sel.json 2>/dev/null
|
|
fi
|
|
rm -rf .accept
|
|
else
|
|
note "tmux not available — markdown smoke skipped (run it on a TTY host)"
|
|
fi
|
|
|
|
echo
|
|
echo "== acceptance: $pass passed, $fail failed, $skip skipped =="
|
|
[ "$fail" -eq 0 ] && { echo "ACCEPTANCE: PASS"; exit 0; } || { echo "ACCEPTANCE: FAIL"; exit 1; }
|