Repository navigation
Highlighting: Make the worker the default and warm it during startup - #1105
Open
masonmcelvain wants to merge 7 commits into
Open
masonmcelvain wants to merge 7 commits into
masonmcelvain wants to merge 7 commits into
Conversation
|
@masonmcelvain is attempting to deploy a commit to the Modem Team on Vercel. A member of the Team first needs to authorize it. |
masonmcelvain
marked this pull request as ready for review
September 15, 2026 17:39
Contributor
|
PR author is not in the allowed authors list. |
Every first-frame benchmark starts its timer after the renderer is already imported, so none of them can observe OpenTUI's module evaluation or its native-library load, which profiles put at roughly 120ms of the ~440ms first frame. Launch `hunk diff` in a real PTY on a small dirty repo and time the first painted review frame from process spawn instead. The script answers the terminal background probe the way a real terminal would so the number reflects a normal launch, and HUNK_BENCHMARK_EXECUTABLE points it at a compiled binary. It joins the default suite so the release gate covers startup end to end. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJ5s3ZBwp9FwFhpee2egXg
On a small diff the default highlight path blocked keyboard input for about a quarter second after the review was on screen: the first file of each language paid one-time Oniguruma grammar compilation on the main thread, and source-backed highlighting tokenizes whole files, so the plain frame appeared and then nothing responded until color landed. Add a `preload` request to the worker protocol that resolves one theme and grammar and tokenizes a short sample so the grammar's root, comment, and string rules compile in the worker. The interactive entrypoint sends one preload per distinct language in the changeset (review order, capped at eight) right after bootstrap and before the OpenTUI import, so compilation overlaps renderer startup. Render requests queue ahead of waiting preloads, so a file that needs color mid-warm-up waits for at most one grammar. Warm-up is best-effort and skipped where the worker is not used at all: Windows compiled binaries and scope-override themes. The protocol version bumps to 5. `themeSupportsHighlightWorker` moves the scope-override check beside the syntax theme naming so the loader, document eligibility, and warm-up share one predicate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Interactive highlighting now uses the syntax worker wherever it is supported instead of behind `--fast`. The inline path remains the fallback for Windows compiled binaries, custom themes with scope overrides, and static (piped) rendering, which gains nothing from a worker. The 40-line minimum goes away. It was checked against source-backed metadata, so nearly every real file already qualified, and with the worker as the default any file that fell below it would have paid the full grammar compile on the main thread for a handful of lines. Every interactive request now takes one path, so grammar compilation happens in the worker exactly once. `--fast` stays accepted as a no-op so existing aliases and configs do not error; it is hidden from `--help` and the public reference and will be removed in a later release. The `offloadLargeDiff` prop plumbing from App down to the highlight hooks is removed, since the decision is no longer per launch; `loadHighlightedDiff` keeps an `offload` option for the static pager, and the document service consults eligibility alone. Tests that need the inline path deterministically use the real eligibility policy under a runtime without worker support, and test files that register worker doubles now dispose them. Measured with the startup benchmark on this branch versus main (source mode, Linux, 7 launches each): the slowest key answer in the 400ms after first paint drops from 105ms to 34ms, first syntax color lands 78ms sooner (639ms to 561ms from spawn), and the first frame costs about 28ms more while the worker thread starts alongside OpenTUI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The worker path was covered by a PTY test that sent a key while a large file highlighted under `--fast`, but nothing exercised the default path on the small multi-language diff where inline grammar compilation blocked input. Add a PTY test that launches a three-grammar review, sends page-down just after the first paint, and requires the answer to arrive within four times the settled answer for the same key once color has landed (or 60ms, whichever is larger). On the inline path the first answer was 4-15x slower; through the worker it matches the settled one. Extend the startup benchmark from the same launch: report the first keyword-colored cell from spawn and the slowest answer among page-down keys sent from first paint through the next 400ms, each answer counted only when an unseen row appears so highlight repaints never count. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`loadHighlightedDiff` marked every worker rejection retryable, and retryable results deliberately stay out of the shared highlight cache so a recreated worker can try again. With the worker now the default path, a permanent refusal such as an extension-registered language Pierre has no grammar for was re-requested on every scroll while the file sat in the prefetch halo, redoing source reads and posting the full metadata to the worker each time. Non-retryable worker errors now fall through to the inline path, which already re-renders an unsupported language as plain text and caches that result once. Retryable failures keep their plain-row placeholder. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The compiled highlight worker control fixture asserts the protocol version by hand, since importing the private worker protocol would cross the CLI fixture's packaging boundary. The preload request bumped that version to 5, so the macOS compiled portability job failed on the old literal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
check:pack requires packages/hunk/README.md to match the repository README, which dropped the `hunk --fast` example. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
masonmcelvain
force-pushed
the
fast-default
branch
from
September 29, 2026 21:51
75efa6e to
cf5f75f
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
--fastthe default with warm workers #1065Syntax highlighting now runs in the worker by default, and the worker starts compiling the review's grammars during startup, before the OpenTUI import. On a small diff the default path used to block keyboard input for roughly a quarter second after the review was already on screen: the first file of each language paid one-time Oniguruma grammar compilation on the main thread, and source-backed highlighting tokenizes whole files. That work now happens in the worker while the renderer loads.
Changes
preloadworker request (protocol v5) resolves one theme and grammar and tokenizes a short sample so the grammar's root, comment, and string rules compile.main.tsxsends one preload per distinct changeset language (review order, capped at 8) after bootstrap and before importing OpenTUI. Render requests queue ahead of waiting preloads, so a visible file waits behind at most one grammar. Warm-up is best-effort and skipped where the worker is not used.supportsHighlightWorkerOffload()holds and the theme has nosyntax_scopesoverrides. Inline stays for Windows compiled binaries, scope-override themes, and static piped output. TheoffloadLargeDiffprop plumbing fromAppdown to the highlight hooks is removed;loadHighlightedDiffkeeps anoffloadoption for the static pager, and the document service consults eligibility alone.HIGHLIGHT_WORKER_MIN_LINESremoved. It was checked against source-backed metadata so nearly every real file already qualified, and with the worker as the default any file below it would have paid the full grammar compile on the main thread for a handful of lines.--fastis a no-op. Still parsed so aliases and existing invocations do not error; hidden from--helpand the public reference; the changeset notes the deprecation for removal in a later release.unsupported-languageand friends) now take the inline path, which re-renders as plain text and caches the result, instead of being marked retryable and re-requested on every scroll while the file sits in the prefetch halo.max(60ms, 4× the settled answer)for the same key once color has landed. Cherry-picks the spawn-inclusive startup benchmark from Startup: begin loading OpenTUI once the plan is interactive, overlapping git bootstrap #1062's investigation and extends it withstartup_first_color_msandstartup_post_paint_key_max_ms.Measurements
Source mode, Linux x64,
benchmarks/startup-first-frame.ts, 7 launches per side, same machine:startup_first_frame_msstartup_first_color_msstartup_post_paint_key_max_msThe +28ms first frame is the worker thread starting alongside the OpenTUI import, the same order as the issue's prototype. The PTY latency test measured the first page-down at 72–105ms on
mainand 6–28ms here across repeated runs.Validation
bun run typecheck,bun run lint,bun run deps:check,bun run check:docsbun run test: 2245 pass, 4 fail. All four reproduce on unmodifiedmainin this environment:test/cli/entrypoint.test.tsandtest/cli/log.test.tspick up my userconfig.toml(watch = true),packages/hunk-jj/src/source.test.tsneedsjjon PATH, andbrokerClient.test.ts > authenticates after a successor becomes healthyis a 5s timeout flake.bun run test:integration: 184 pass, 1 fail. The failure iswatch-start-integration.test.ts's teardown assertion (child.exitCodestill null 500ms after SIGKILL), which fails 2 of 4 runs onmainas well.hunk diffandhunk show HEAD~1on this repository at 140×30, unified layout, github-dark-default; navigation and color land as before.hunk show HEAD~1 | head,hunk --fast show HEAD~1 | head, andhunk diff --helpfrom source.supportsHighlightWorkerOffloadstill gates it, warm-up skips it).Follow-ups
hunk log's interactive history surface does not warm the worker; it has no file list when the plan is selected, so its first review still starts a cold worker.--fastin a later release.🤖 Generated with Claude Code