diff --git a/docs/opentui-dev-handoff.md b/docs/opentui-dev-handoff.md index c6a6565a4cb..dd8b0dc8aef 100644 --- a/docs/opentui-dev-handoff.md +++ b/docs/opentui-dev-handoff.md @@ -41,7 +41,8 @@ run benches SEQUENTIALLY (the harness already wraps SUTs in `systemd-run … Mem - `docs/opentui-env-flags.md` — the consolidated env-flag ledger (master switch / user / dev / plumbing). - `docs/opentui-upstream-alignment.md` — forkless invariant, `boundary/` shim ledger, the per-release OpenTUI upgrade playbook (native-yoga is coming upstream — re-tune windowing margins when it lands). -- `bench/README.md` — the bench suite (cells, harness, live-attach, memwatch). +- the bench suite (cells, harness, live-attach, memwatch) now lives in its own + repo: **tui-bench** (`github.com/NousResearch/tui-bench`); see its `README.md`. - `ui-opentui/README.md` — Node 26 onboarding (fnm setup that doesn't disturb other projects). - `docs/plans/ink-memory-adversarial-review.md` — Ink's memory weaknesses (F1–F10, the turnabout). - `docs/plans/gateway-death-forensics.md`, `docs/plans/workorder-2026-06-11-results.md`, @@ -70,8 +71,9 @@ run benches SEQUENTIALLY (the harness already wraps SUTs in `systemd-run … Mem `export HERMES_TUI_DIAGNOSTICS=1` in the shell rc turns on, for every session: the `/mem` + `/heapdump` slash commands, window-stats, and **fleet memory self-logging** to `~/.hermes/logs/memwatch/-.jsonl`. Aggregate all sessions with -`node bench/memwatch-report.mjs` (per-session baseline/peak/slope + SLOPE/PEAK/MOUNTED anomaly -flags). Chase a flagged session with `bench/live-attach.sh --heap`. The discipline: live +`node memwatch-report.mjs` from the **tui-bench** repo +(`github.com/NousResearch/tui-bench`) (per-session baseline/peak/slope + SLOPE/PEAK/MOUNTED anomaly +flags). Chase a flagged session with tui-bench's `live-attach.sh --heap`. The discipline: live anomaly → encode as a bench cell → fix → validate against live sessions again. ## Current state (2026-06) + the ranked backlog @@ -85,7 +87,7 @@ catalogs hydrated at boot**. Ranked next levers: `_resolve_tui_heap_mb`; both engines are Node now so both inherit it. Ink half = separate gated commit (shipping engine). Measured −90MB at bench scale. 2. **cg_peak harness fix** (small): the cgroup `memory.peak` field is polluted (shared across runs) — - reset/scope it before quoting `bench/report.html` again. Trust `vmhwm_kb` + `samples[].rss_kb`. + reset/scope it before quoting tui-bench's `report.html` again. Trust `vmhwm_kb` + `samples[].rss_kb`. 3. **New bench cells** (before W1, as its baselines): `resume-1900` (real p99 shape: time-to-first- paint + post-hydration RSS) and `10MB-tool-output` (the F1 byte-unbounded class). Run BOTH engines. 4. **Catalog lazy-load** (new, promoted by live data): don't hydrate 1,185 tools at boot — fetch on diff --git a/docs/opentui-env-flags.md b/docs/opentui-env-flags.md index 23b7ba86ec5..877a7e064c1 100644 --- a/docs/opentui-env-flags.md +++ b/docs/opentui-env-flags.md @@ -27,11 +27,11 @@ classified by who should ever touch it. The design rule shipped with this doc: |---|---|---| | `HERMES_TUI_WINDOWING` | **on** | `0` = bit-exact pre-windowing renderer (every row mounts; cap clamps back to 1000). The A/B + regression escape hatch. | | `HERMES_TUI_WINDOW_IDLE_MS` | ~1000 | Idle-measure pulse cadence (the spacer-exactness march). Test knob. | -| `HERMES_TUI_WINDOW_STATS` | = `HERMES_TUI_DIAGNOSTICS` | Exposes live/peak mounted-row counters (`globalThis.__hermesTuiWindowStats`) for bench/live-attach reads. | -| `HERMES_TUI_MEMLOG` | = `HERMES_TUI_DIAGNOSTICS` | In-process 1Hz memory self-sampling (`boundary/memlog.ts`) → `~/.hermes/logs/memwatch/-.jsonl` (rss/heap/external + mounted rows; 14-day retention). Fleet view: `node bench/memwatch-report.mjs`. The "monitor all my sessions" answer: one `export HERMES_TUI_DIAGNOSTICS=1` in your shell rc covers every session. | +| `HERMES_TUI_WINDOW_STATS` | = `HERMES_TUI_DIAGNOSTICS` | Exposes live/peak mounted-row counters (`globalThis.__hermesTuiWindowStats`) for tui-bench's live-attach reads. | +| `HERMES_TUI_MEMLOG` | = `HERMES_TUI_DIAGNOSTICS` | In-process 1Hz memory self-sampling (`boundary/memlog.ts`) → `~/.hermes/logs/memwatch/-.jsonl` (rss/heap/external + mounted rows; 14-day retention). Fleet view: `node memwatch-report.mjs` from the tui-bench repo (`github.com/NousResearch/tui-bench`). The "monitor all my sessions" answer: one `export HERMES_TUI_DIAGNOSTICS=1` in your shell rc covers every session. | | `HERMES_TUI_LOG_LEVEL` / `HERMES_TUI_LOG_FILE` | engine defaults | Logging verbosity/destination (`/logs` reads the ring buffer regardless). Deliberately independent of the master switch — support often wants logs without the full diag surface. | -## 4. Internal plumbing (set by the launcher/bench/tests — humans never set these) +## 4. Internal plumbing (set by the launcher/tui-bench/tests — humans never set these) | var | set by | effect | |---|---|---| @@ -46,7 +46,7 @@ classified by who should ever touch it. The design rule shipped with this doc: - Regular user, normal day: zero flags, zero diagnostic commands visible. - "My TUI feels heavy" support flow: `HERMES_TUI_DIAGNOSTICS=1 hermes` → `/mem` for the live numbers, `/heapdump` for a snapshot to attach, window stats - exposed for `bench/live-attach.sh ` to read. + exposed for tui-bench's `live-attach.sh ` to read. - Developer profiling: same master switch + the individual knobs (`HERMES_TUI_WINDOWING=0` A/B, `WINDOW_IDLE_MS` tuning) as needed. - Anything in section 4 appearing in a user-facing doc is a bug. diff --git a/docs/opentui-memory-story.md b/docs/opentui-memory-story.md index 63ec531c66e..1614c7335d5 100644 --- a/docs/opentui-memory-story.md +++ b/docs/opentui-memory-story.md @@ -1,7 +1,7 @@ # How the OpenTUI transcript got from 686MB to ~300MB — the full story *For: glitch. Branch: `feat/opentui-memory-window`. Everything here is measured, -not vibes; every number has a result JSON in `bench/results/`.* +not vibes; every number has a result JSON in the **tui-bench** repo's `results/` (`github.com/NousResearch/tui-bench`).* --- @@ -200,7 +200,7 @@ the pre-windowing TUI literally could not do. - Everything is behind `HERMES_TUI_WINDOWING` (default on, `0` = bit-exact old behavior) — a one-env escape hatch if anything feels off in real use. -*Where to verify: `bench/results/` (every number above), the design+gates doc +*Where to verify: the **tui-bench** repo's `results/` (`github.com/NousResearch/tui-bench`; every number above), the design+gates doc `docs/plans/opentui-transcript-windowing.md`, tests in `ui-opentui/src/test/window.test.ts` and `transcriptWindow.test.tsx` (the zero-jank invariants are literal assertions: identical scrollHeight windowed diff --git a/ui-opentui/README.md b/ui-opentui/README.md index 64d1a2f2041..51a4995b5b0 100644 --- a/ui-opentui/README.md +++ b/ui-opentui/README.md @@ -31,7 +31,7 @@ plus an `.nvmrc` shim (`echo 26 > .nvmrc`) if you rely on auto-switching. - **Native modules are ABI-locked.** A `node_modules` installed under Node 20/22 will not load under 26 (and vice versa) — run `npm ci` (or - `npm rebuild`) after switching versions. Same applies to `bench/`'s node-pty. + `npm rebuild`) after switching versions. Same applies to the **tui-bench** repo's node-pty (`github.com/NousResearch/tui-bench`). - **Global npm packages don't follow** between versions (per-version prefix); reinstall the few you need, or don't use globals. - **Editor terminals** (Zed/VS Code) need the `fnm env` line in your shell rc; @@ -49,5 +49,5 @@ HERMES_TUI_MOUSE=1 node --experimental-ffi --no-warnings dist/main.js ``` Gates: `npm run check` (typecheck + lint + tests). Memory/perf benchmarks live -in `../bench/` (see its README). Transcript windowing (memory architecture) is +in the **tui-bench** repo (`github.com/NousResearch/tui-bench`; see its README). Transcript windowing (memory architecture) is documented in `../docs/plans/opentui-transcript-windowing.md`. diff --git a/ui-opentui/src/boundary/memlog.ts b/ui-opentui/src/boundary/memlog.ts index 0f832f5e82f..84f62afe4ed 100644 --- a/ui-opentui/src/boundary/memlog.ts +++ b/ui-opentui/src/boundary/memlog.ts @@ -5,7 +5,7 @@ * sessions": instead of an external watcher chasing pids, every TUI session * logs its OWN samples when enabled, keyed by pid + boot time, into * `~/.hermes/logs/memwatch/`. Aggregate across sessions with - * `bench/memwatch-report.mjs`. + * the tui-bench repo's `memwatch-report.mjs` (github.com/NousResearch/tui-bench). * * Gating (docs/opentui-env-flags.md): `HERMES_TUI_MEMLOG` — defaults to the * `HERMES_TUI_DIAGNOSTICS` master switch, individually overridable either way. diff --git a/ui-tui/packages/hermes-ink/src/ink/memSampler.ts b/ui-tui/packages/hermes-ink/src/ink/memSampler.ts index d72c7604d09..1b8486d3c70 100644 --- a/ui-tui/packages/hermes-ink/src/ink/memSampler.ts +++ b/ui-tui/packages/hermes-ink/src/ink/memSampler.ts @@ -3,7 +3,7 @@ // walks the forked reconciler's root DOM tree and writes one NDJSON line per // sample to that fd: {"t":,"dom":,"yoga":}. // -// Used by bench/ (the instrumented node-count runs — see +// Used by the tui-bench repo (the instrumented node-count runs — see // docs/plans/opentui-bench-suite.md). RSS from instrumented runs is flagged and // never headlined; this sampler exists ONLY as the mechanism witness for the // transcript-growth claim. It writes to a dedicated fd (3 by convention), never diff --git a/ui-tui/packages/hermes-ink/src/ink/reconciler.ts b/ui-tui/packages/hermes-ink/src/ink/reconciler.ts index 5fdce3bf9cd..c4df9ce3641 100644 --- a/ui-tui/packages/hermes-ink/src/ink/reconciler.ts +++ b/ui-tui/packages/hermes-ink/src/ink/reconciler.ts @@ -147,7 +147,7 @@ function applyProp(node: DOMElement, key: string, value: unknown): void { export const dispatcher = new Dispatcher() -// --- SCROLL PROFILING (bench/scroll-e2e.sh reads via getLastYogaMs) --- +// --- SCROLL PROFILING (tui-bench's scroll-e2e.sh reads via getLastYogaMs) --- // Set by onComputeLayout wrapper in ink.tsx; read by onRender for phases. let _lastYogaMs = 0 let _lastCommitMs = 0