fix(tui): address PR #13231 review comments

Six small fixes, all valid review feedback:

- gatewayClient: onTimeout is now a class-field arrow so setTimeout gets a
  stable reference — no per-request bind allocation (the whole point of
  the original refactor).
- memory: growth rate was lifetime average of rss/uptime, which reports
  phantom growth for stable processes. Now computed as delta since a
  module-load baseline (STARTED_AT). Sanity-checked: 0.00 MB/hr at
  steady-state, non-zero after an allocation.
- hermes_cli: NODE_OPTIONS merge is now token-aware — respects a
  user-supplied --max-old-space-size (don't downgrade a deliberate 16GB
  setting) and avoids duplicating --expose-gc.
- useVirtualHistory: if items shrink past the frozen range's start
  mid-freeze (/clear, compaction), drop the freeze and fall through to
  the normal range calc instead of collapsing to an empty mount.
- circularBuffer: throw on non-positive capacity instead of silently
  producing NaN indices.
- debug slash help: /heapdump mentions HERMES_HEAPDUMP_DIR override
  instead of hardcoding the default path.

Validation: tsc clean, eslint clean, vitest 102/102, growth-rate smoke
test confirms baseline=0 → post-alloc>0.
This commit is contained in:
Brooklyn Nicholson 2026-04-20 19:09:09 -05:00
parent 82b927777c
commit e1ce7c6b1f
6 changed files with 30 additions and 16 deletions

View file

@ -80,7 +80,10 @@ export async function captureMemoryDiagnostics(trigger: MemoryTrigger): Promise<
const smapsRollup = await swallow(() => readFile('/proc/self/smaps_rollup', 'utf8'))
const nativeMemory = usage.rss - usage.heapUsed
const bytesPerSecond = uptimeSeconds > 0 ? usage.rss / uptimeSeconds : 0
// Real growth rate since STARTED_AT (captured at module load) — NOT a lifetime
// average of rss/uptime, which would report phantom "growth" for a stable process.
const elapsed = Math.max(0, uptimeSeconds - STARTED_AT.uptime)
const bytesPerSecond = elapsed > 0 ? (usage.rss - STARTED_AT.rss) / elapsed : 0
const mbPerHour = (bytesPerSecond * 3600) / (1024 * 1024)
const potentialLeaks = [
@ -172,6 +175,8 @@ export function formatBytes(bytes: number): string {
const UNITS = ['B', 'KB', 'MB', 'GB', 'TB']
const STARTED_AT = { rss: process.memoryUsage().rss, uptime: process.uptime() }
// Returns undefined when the probe isn't available (non-Linux paths, sandboxed FS).
const swallow = async <T>(fn: () => Promise<T>): Promise<T | undefined> => {
try {