Four per-render costs, each with a proposed fix. Three carry a behavior change, one is a ~20-25 file
diff, so they are worth agreeing before the patches.
Windows 11, bun 1.3.13, node 26.7.0. Corpus 18,837 transcripts, 16.2 GiB.
1. jsonl-blocks.ts:183 reads past its own 48 h cap. Parses every byte of every selected
transcript. A backwards scan stopping at the first pre-48 h entry gives the same answer.
|
current |
bounded |
| total |
10,443-16,186 ms |
2,165-3,056 ms |
| bytes |
1,867 MiB |
219 MiB |
| peak RSS |
6.4-8.2 GiB |
~460 MiB |
Also fixes data loss: readFileSync on a 1,359 MiB transcript throws ERR_STRING_TOO_LONG under
node, the bare catch at :221 returns [], 41,652 timestamps vanish (#550's class).
Behavior change: with no 5 h gap in 48 h and pre-48 h history in a selected file, the block phase
shifts.
2. Git widgets run ten commands where three suffice. 626.3 → 205.3 ms, 21 fewer processes per cold
render, via status --porcelain=v2 --branch -z + diff HEAD --shortstat + remote get-url. Spawn is
~90% of a git call on Windows. Three behavior changes: branch.oid at 7 chars ignores core.abbrev;
conflicted files are double-counted today (git.ts:433-465); getGitChangeCounts double-counts a line
staged then re-modified.
3. chcp.com spawns every Windows render (ccstatusline.ts:325). 35-104 ms, 13-20% of a render;
removing it 401 → 288 ms. The code page is console-wide and persistent, so gating on a session_id
marker keeps #186 fixed.
4. Widget barrel evaluates React and Ink per render. widget-manifest.ts:5 loads all 88 widget
modules; six import ink/react at module scope for renderEditor. 1.57 MB, 55-140 ms, 6-24 MB per
repaint. Stubbed to empty modules, output is byte-identical. Fix is ~20-25 files.
Rejected: lazy import() on runTUI (no win, +4 MB, barrel pulls React anyway); directory-mtime
pruning (NTFS does not bump on append); batched async stat (getBlockMetrics runs inside a sync
render()); fdir withStats (absent on tinyglobby's version).
Four per-render costs, each with a proposed fix. Three carry a behavior change, one is a ~20-25 file
diff, so they are worth agreeing before the patches.
Windows 11, bun 1.3.13, node 26.7.0. Corpus 18,837 transcripts, 16.2 GiB.
1.
jsonl-blocks.ts:183reads past its own 48 h cap. Parses every byte of every selectedtranscript. A backwards scan stopping at the first pre-48 h entry gives the same answer.
Also fixes data loss:
readFileSyncon a 1,359 MiB transcript throwsERR_STRING_TOO_LONGundernode, the bare
catchat:221returns[], 41,652 timestamps vanish (#550's class).Behavior change: with no 5 h gap in 48 h and pre-48 h history in a selected file, the block phase
shifts.
2. Git widgets run ten commands where three suffice. 626.3 → 205.3 ms, 21 fewer processes per cold
render, via
status --porcelain=v2 --branch -z+diff HEAD --shortstat+remote get-url. Spawn is~90% of a git call on Windows. Three behavior changes:
branch.oidat 7 chars ignorescore.abbrev;conflicted files are double-counted today (
git.ts:433-465);getGitChangeCountsdouble-counts a linestaged then re-modified.
3.
chcp.comspawns every Windows render (ccstatusline.ts:325). 35-104 ms, 13-20% of a render;removing it 401 → 288 ms. The code page is console-wide and persistent, so gating on a
session_idmarker keeps #186 fixed.
4. Widget barrel evaluates React and Ink per render.
widget-manifest.ts:5loads all 88 widgetmodules; six import
ink/reactat module scope forrenderEditor. 1.57 MB, 55-140 ms, 6-24 MB perrepaint. Stubbed to empty modules, output is byte-identical. Fix is ~20-25 files.
Rejected: lazy
import()onrunTUI(no win, +4 MB, barrel pulls React anyway); directory-mtimepruning (NTFS does not bump on append); batched async
stat(getBlockMetricsruns inside a syncrender());fdirwithStats(absent on tinyglobby's version).