Repository navigation
fix(deps): update dependency @opentui/core to v0.8.0 - #465
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
from
August 24, 2026 19:06
d94b49b to
5718e8e
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
3 times, most recently
from
August 27, 2026 06:17
3787cdd to
658be89
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
12 times, most recently
from
August 31, 2026 05:12
3f9cf28 to
b75c4b8
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
7 times, most recently
from
September 6, 2026 06:06
9171811 to
01bcfd1
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
3 times, most recently
from
September 8, 2026 02:01
f1e9d16 to
58804d7
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
16 times, most recently
from
September 21, 2026 17:03
d80a780 to
24295eb
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
2 times, most recently
from
September 22, 2026 22:43
f4a813d to
e075063
Compare
renovate
Bot
force-pushed
the
renovate/opentui-core-0.x
branch
10 times, most recently
from
September 29, 2026 20:56
70d54ba to
0354525
Compare
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.
Note
This PR body was truncated due to platform limits.
This PR contains the following updates:
0.5.10→0.8.0Release Notes
anomalyco/opentui (@opentui/core)
v0.8.0Compare Source
Most of 0.8.0 makes each frame cheaper. In 0.7.0, every frame cleared and repainted the whole screen and compared every row with the terminal, even when only a spinner had moved. Now an unchanged frame paints nothing, and a frame with a small change repaints only the rows around it. In OpenCode, a frame with a spinner or a streamed line does about a twentieth of the cell operations it did.
ScrollBox now scrolls and follows new content in native code. Animations share one clock: before, an app with several animations could draw twice as many frames as the animations needed.
The native input parser is still opt-in. It now keeps a mouse wheel report that a slow link splits, which the default parser can type into the focused input as text. To try it, set
OTUI_NATIVE_INPUT_PARSER=1, or passexperimental_nativeInput: trueto the renderer.Wide emoji sequences, such as a family emoji in tmux, draw at their full width, and long wrapped or highlighted lines draw their last rows as fast as their first.
In 0.7.0, a ScrollBox was twelve scene nodes. It kept its scroll position in four copies, followed its sticky edge through a six-flag state machine, and learned its range from two separate resize hooks. Because the viewport size and the content size came from different hooks, a frame in which the box and its content grew together reset the position to 0. Vertical viewport padding left the last rows out of reach, and the scrollbar thumb was half a cell until the first terminal resize. In 0.8.0, a ScrollBox is one box with a native scroll control. After each layout solve, native code computes the range, follows the sticky edge, clamps the offset, and shows or hides the bars, all from one layout. Following new content no longer needs a round trip to JavaScript.
That change has a cost for code that reached into the parts.
wrapper,viewport,content, and the two scrollbars are now views of the native state, not renderables. They still have geometry, colors, padding, and their events, but they have no children of their own. Children of a ScrollBox report the ScrollBox as theirparent, and a press on a scrollbar targets the ScrollBox. Code that compared a node with the content part now compares it with the ScrollBox itself:With the scroll state in native code, a scroll can also wait for layout. Before, an app that loaded older messages above the reader and then corrected the position had to wait two animation frames, and the reader saw one frame at the old position. Now
scrollToandscrollByapply again after the next frame's layout, andanchorholds a row in place while the content above it changes. Release the anchor inafterLayout, so that the frame that lays out the new rows still holds the place:In an OpenCode transcript, this took the shifted frames during a backfill from 1 to 0, and the in-between frames over 6 message jumps from 6 to 0.
An animation slower than the renderer, such as a spinner, used to have two options. It could set
live: true, which runs the loop attargetFpsand keepsrenderer.idle()from resolving. Or it could run its own timer that callsrequestRender(). With timers, every component gets its own frames, so three components at 20, 12.5, and 10 fps drew 40 frames per second.renderer.onAnimationTickputs every subscriber on one clock. Due times are multiples of1000 / fps, so equal rates tick together. Each frame, whatever its cause, also runs every tick that is due within its tolerance. The same three components now draw 20 frames per second, and OpenCode during an agent turn draws 26 instead of 52 to 55:A renderable can set
animationFpsinstead. React components useuseAnimationTick, and Solid components useonAnimationTick.Before 0.8.0, OpenTUI wrapped every frame in synchronized output (
CSI ? 2026 h…CSI ? 2026 l), even when the terminal never reported mode 2026. Over a slow link, those wrappers cost bytes on every frame. A tmux between the app and the link redraws each line that an update touched when the update ends, so a streaming scene sent 64 KB/s instead of 41 KB/s. On a 48 KB/s SSH link, that is a lag of 2.0 s instead of 75 ms. The new default,synchronizedOutput: "auto", removes the wrapper in a remote session once the startup replies arrive, but only when the terminal did not report mode 2026, or when the app writes toprocess.stdoutinside tmux, screen, or Zellij on its own host. In the multiplexer case, OpenTUI gives up whole frames to save bytes, so tmux can show partial frames. If you want whole frames on a slow link, setsynchronizedOutput: "always".Breaking changes
wrapper,viewport,content,verticalScrollBar, andhorizontalScrollBarof a ScrollBox are facade objects (ScrollBoxWrapper,ScrollBoxViewport,ScrollBoxContent,ScrollBoxBar), not renderables. Children report the ScrollBox as theirparent, so compare a node with the ScrollBox, not withscroll.content. See ScrollBox. (#1805)slider,startArrow, orendArrow,overflowis always"hidden",getChildrenCount()counts the rows, andprimaryAxisfollows the content direction. ScrollBox ignores renderable options on its parts outside each part's supported color, layout, padding, bar, and callback fields, and viewport padding that is not whole cells throws. See ScrollBox. (#1805)RenderContextrequires theclockandonAnimationTickfields, so a customRenderContextmust implement them. The renderer and the scrollback snapshot context supply both. See Custom renderables. (#1814, #1803)Renderable._hasFocusedDescendantfield is removed, so a subclass that reads it getsundefined. ReadhasFocusedDescendantinstead, and useFFIRenderLib.contextDrawSceneBody()instead ofcontextDrawSceneText(). See Custom renderables. (#1778)OT_SCENE_RECORD_SCENE_TEXTis nowOT_SCENE_RECORD_SCENE_BODY, andot_buffer_draw_scene_textis nowot_buffer_draw_scene_body, with the same value and layout. Thereservedfield ofot_scene_statsis nowdamage_rows. See C. (#1778, #1783)CliRendererexists only as the renderer of a Session, andContext.drawSceneTextanddrawSceneTextOnare nowdrawSceneBodyanddrawSceneBodyOn.BufferedOutputand the standalone create, render, and setup calls are removed, so render through a Session. See Zig. (#1806, #1778)Added
renderer.onAnimationTick(fps, callback, { tolerance })runs callbacks on one shared animation clock, so animations at different rates share frames.Renderable.animationFpsticks the protectedonAnimationTick()of a node while it is drawn, and aTimelinewith aframeRatebelowtargetFpsticks on the clock. See Animation and Timeline. (#1803)useAnimationTick(fps, callback, options?)subscribes a component to the shared animation clock and commits state updates from the callback in the tick's frame. Anundefinedrate pauses it. See React bindings. (#1803)onAnimationTick(fps, callback, options?)subscribes a component to the shared animation clock, andfpscan be anAccessor<number | undefined>that returnsundefinedto pause it. See Solid bindings. (#1803)ScrollBoxRenderable.anchor(node)keeps a row at its place in the viewport through layout changes, andafterLayout(callback)runs once after the next frame's layout and before it paints.scrollChildIntoView()accepts a node, analignof"nearest","start", or"end", and aninset. See ScrollBox. (#1811)ScrollBoxRenderable.scrollXandscrollYread and update which axes scroll after construction. See ScrollBox. (#1805)nativeSceneVerify, on by default, compares each frame that retained paint skips or repaints in part with a full repaint, and it throws on a mismatch. See Testing. (#1783)TERMnamesrexorxterm-rex. See Terminal capabilities. (#1819)ot_scene_set_scroll,ot_scene_scroll_to,ot_scene_get_scroll,ot_scene_scroll_request, andot_scene_set_scroll_arrowconfigure, scroll, and read it, andOT_SCENE_HOOK_SCROLLasks for anOT_SCENE_FRAME_SCROLLrequest when its state changes. See Frames and output. (#1798, #1811)ot_scene_stats.damage_rowscounts the rows that a frame diffs, and the newOT_SCENE_FULL_PATH_*bits give the reason for a full repaint.OT_SCENE_DEBUG_VERIFYcompares retained frames with a full repaint. See Frames and output. (#1783, #1808)OT_EDIT_POSITION_ENDandOT_EDIT_POSITION_PREV_CHAR, alsoNativeEditPositionQuery.EndandPrevCharin Core, read the end of the text and the position that Left moves to. They do not move the cursor. See C. (#1848)OT_INPUT_EXPECT_SENTINELholds split terminal replies while the host waits for a DA1 reply.OT_TERMINAL_REPLY_SENTINEL,OT_TERMINAL_SYNC_ALWAYS,OT_TERMINAL_SYNC_NEVER, andOT_TERMINAL_HOST_MULTIPLEXERset the reply sentinel and the synchronized-output policy of a Session. See Host I/O and time. (#1793, #1816, #1851)Changed
synchronizedOutputoption defaults to"auto", which removes the synchronized-output wrapper in some remote sessions after the startup replies arrive. Set"always"for the old behavior, or"never"to never wrap a frame. See Renderer. (#1851)capabilitiesand repaints only when the capabilities change. After startup, handlers added withaddInputHandlerno longer see these replies, and the theme mode follows each OSC 11 reply. See Terminal capabilities. (#1807)drawFrameBuffer()copies a source withoutrespectAlphaat full opacity, also when the screen or the source holds a grapheme or a link, so transparent source cells show as holes. A transparent box border of space glyphs keeps the glyph below it in every case. See Buffer API. (#1810)zIndexpaint in attachment order. A child whosezIndexchanges and then goes back to its old value gets its original paint position back. See Renderables. (#1812)clock, so a customClockdrives it. See ScrollBox. (#1805, #1814)scrollTo()andscrollBy()scroll at once and again after the next frame's layout, so a scroll made in the same tick as a content change uses the new layout.scrollTo(scrollHeight)andscrollTo(Infinity)stay at the end after the content grows. See ScrollBox. (#1811)@opentui/solidand@opentui/keymapacceptsolid-js^1.9.12as a peer dependency instead of1.9.12alone. See Solid bindings. (#1786)Fixed
onChangeoptions run. See ScrollBox. (#1805, #1798)/mnt/wslg/runtime-dir/$WAYLAND_DISPLAY. On WSLg, a read that loses focus to another window maps a new helper surface, at most two times, instead of failing. See Clipboard. (#1845, #1849)empty. See Clipboard. (#1844)timeoutMs: 1000that an unresponsive owner blocked took 17.3 s. See Clipboard. (#1847)syntaxStyleorfgof aMarkdownRenderablerestyles list markers, and withinternalBlockMode: "top-level"it also restyles list items and table cells. Before, they kept the old theme's colors. See Markdown. (#1841)wcwidth, a cluster can span up to 16 cells, so ZWJ families of 6 or 8 cells no longer leave blanks or stale cells. A wider cluster draws as blank cells of its width, and OSC 66 explicit width is capped at 7 cells and padded with spaces. See Text and terminal cells. (#1779)TimeToFirstDrawRenderableandLineNumberRenderableat a fractional position no longer fail the frame, and both draw correctly withbuffered: true. See TimeToFirstDraw and Line number gutter. (#1826)super.renderSelf()on anArrowRenderableat a fractional position no longer fails the frame,super.renderSelf()on aSliderRenderablematches native thumbs at negative fractional positions, and a bufferedBoxRenderable,SliderRenderable, orArrowRenderabledraws at its own origin instead of shifted. See Custom renderables. (#1799, #1778)ESC [. Before,✓arrived as Alt keys and a wheel notch typed<64;87;26M. 8-bit Meta input now reads as UTF-8. See Keyboard input. (#1791, #1794)Security
@opentui/solidusesbabel-preset-solid1.9.16. Solid releases before 1.9.16 depend on Seroval versions with a critical advisory (GHSA-p6vx-979v-rg4c), so installsolid-js1.9.16 or later. See Solid bindings. (#1786)API changes and documentation: https://opentui.com/docs/releases/0.8.0
What's Changed
New Contributors
Full Changelog: anomalyco/opentui@v0.7.0...v0.8.0
v0.7.0Compare Source
Before 0.7.0, typing one character in a 10,000-line Textarea laid out all 10,000 lines before the key call returned, and the Yoga measure of the next frame walked them again. Typing and pasting slowed down with the size of the document, and word wrap paid the most. In 0.7.0, an edit only records that the view must scroll to the cursor. The layout runs once, at the next read of the viewport or the visual cursor, or at the next frame. It compares the text with the text of the last layout and lays out only the lines around the change. An insert, a delete, an undo, or a join lays out one line. Enter lays out two lines, and a 100-line paste lays out 101.
A read that needs the layout still pays for it.
visualCursorlays out the text when an edit is pending.cursorOffsetreads the logical cursor and does not lay out the text. To check after each key whether the cursor is at the start of the text, comparecursorOffset:Before 0.7.0,
Renderablefound the hooks of each node by reflection. It scanned the property descriptors of every new instance two times. For 10,000 rows of a Text subclass that overridesrenderSelf, this took 20,000 scans and 160,000 descriptor reads. Now a node reads its hooks from its class once, at construction. Prototype methods withsuper, constructor options, and assignments torenderBefore,renderAfter,onLifecyclePass, andonSizeChangework as before.Three kinds of code must change. First, a hook that you add by reflection does nothing until you call
node.refreshHooks(). Examples are an instance class field,Object.defineProperty(), or an assignment to therenderSelforonUpdateof one node. Second, a patch or spy on a prototype method after nodes exist does not reach those nodes, and untyped JSX props such asonUpdateandonResizehave no effect. Third,renderBefore,renderAfter, andonLifecyclePassare now accessors. A class field that overrides one of them is a TypeScript error, so assign the hook in the constructor. AnonLifecyclePassclass field still runs, because attaching the node registers it.A class that used
defineNativeIntegration()must now declare the description directly. Without the type annotation,kinddoes not keep its literal type:The
nativeSceneWorkBudgetrenderer option let a frame yield to the event loop during native preparation. OpenTUI, its SSH package, and OpenCode did not set it. On a 10,000-line log, it cut the longest native slice by about 0.15 ms but used 27% more native time. With one mutation per event-loop turn, each yield started preparation again, until the frame failed withLayoutLimit. A renderer that scrolled or streamed under a budget showed no frames. Now preparation and paint finish in one call. A C binding built against the old header passes every argument after the removedmax_work_itemsone slot off, so the ABI version changes. To update a binding, generate it again from the newopentui.h. Then remove themax_work_itemsargument and anyOT_SCENE_FRAME_YIELDcase, and use the 224-byteot_scene_statsrecord. Thework_budgetofot_session_pumpis a different budget and does not change.0.7.0 also adds a native input parser. The TypeScript parser parses each framed unit again with regular expressions, and its structure caused bugs that are hard to fix in place. These bugs include lost Escape-prefixed events, empty Alt key names, wrong Alt keys for non-ASCII characters, wheel releases that ended drags, and negative X10 coordinates. The native parser is a bounded state machine that does not allocate, and it handles all of these cases. It is off by default while timing and buffering edge cases are tested. To try it, set
OTUI_NATIVE_INPUT_PARSER=1or create the renderer with the option:With
OTUI_NATIVE_INPUT_SHADOW=1, the renderer also runs the other parser. It writes a[stdin-shadow]warning for each event that the two parsers report differently. The warnings contain your input, so protect them as you would a stdin log. To report a parser bug, include a log fromOTUI_STDIN_LOG. The native parser is bounded, so it ignoresstdinParserMaxBufferBytes.Known issue: when the terminal hangs up, as when an SSH connection closes, the renderer prints
Error disabling raw modeandNative scene shutdown failederrors with stack traces to stderr. The process still exits with code 0.Breaking changes
nativeSceneWorkBudgetthrows at construction, so remove the option.NativeSceneFrame.Yieldand themaxWorkItemsargument ofFFIRenderLib.sceneFrameStep()are removed. See How Core uses native. (#1719)NativeSceneFrameRequest.geometryRevisionis removed. See How Core uses native. (#1760)ot_scene_frame_step_with_geometryno longer has itsmax_work_itemsparameter,OT_SCENE_FRAME_YIELDis removed, andOT_CONTEXT_ABI_VERSIONis 2. Build bindings again from the newopentui.h, because records with version 1 fail withOT_UNSUPPORTED_VERSION. See C. (#1719)ot_scene_statschanges from 64 to 224 bytes, andot_scene_get_statsreturnsOT_INVALID_ARGUMENTfor the 64-byte record. Generate the record again from the new header. See Frames and output. (#1722)Context.sceneFrameStepWorkBudgetedis removed,sceneFrameStepWithRecordingno longer takesmax_work_items, andreplaceOwnedStyledTextno longer takes aSyntaxStyle.OwnedStyledChunknow holds a style value, and the module no longer exports 12 extra span-feed symbols. See Zig. (#1719, #1768, #1784)Renderable.defineNativeIntegration()andNativeRenderableIntegration.constructionare removed. Declarestatic override readonly nativeIntegration: NativeRenderableIntegration = { ... }withoutconstruction. See Custom renderables. (#1754)refreshHooks(). A class field that overridesrenderBefore,renderAfter, oronLifecyclePassis a TypeScript error (TS2610), so assign it in the constructor. See Custom renderables. (#1754)TextBufferRenderable._textBufferSyntaxStylefield is removed. Styled text keeps its styles in the text buffer, so remove code that reads the field. See Code. (#1775)translateXandtranslateYthrowRangeErrorfor values outside the 32-bit float range of the layout setters. Before, such values did not paint. See Layout. (#1682)Added
experimental_nativeInputrenderer option, orOTUI_NATIVE_INPUT_PARSER, parses stdin with a new native parser.OTUI_NATIVE_INPUT_SHADOWruns both parsers and logs each event that they report differently. See Environment variables. (#1592, #1787)ot_session_input_feed()parses terminal input into caller-ownedot_input_eventrecords, a payload buffer, and anot_input_drainsummary, and it does not allocate.ot_session_input_expect()sets the replies that the parser expects, andot_session_input_reset()clears the parser state.FFIRenderLib.sessionInputFeed(),sessionInputExpect(), andsessionInputReset()wrap them. See Host I/O and time. (#1592)getNativeStats().frameWork, also ingetStats(), counts the work of the last presented scene frame, such as Yoga solves, view preparations, and painted cells. The test renderer optionnativeSceneFullFramemakes each frame rebuild its work lists, so tests can compare the counts. See Rendering diagnostics. (#1722)ot_scene_statsreports the work of the last presented scene frame.ot_scene_set_debug_flags()withOT_SCENE_DEBUG_FULL_FRAMEforces the full frame path, andfull_path_reasonsuses theOT_SCENE_FULL_PATH_*bits. See Frames and output. (#1722)_paintWidthand_paintHeightofRenderablegive the size that arenderSelf()paints, clamped to the cell range that drawing accepts. See Custom renderables. (#1682)Changed
textAlign,truncate,tabIndicator,tabIndicatorColor, and the editor scroll margin. See Rendering pipeline. (#1755, #1767, #1774)wrapMode: "none", a line that is scrolled right skips the text to the left of the viewport by chunk and cluster. An idle editor with one 256 KiB line no longer walks the line on each frame. See Textarea. (#1777)x,y,width, andheightuse the cached layout without a native call or a flush.getLayout()andgetComputedLayout()call native code on every call, and a rejected staged write shows at the next flushing call. See Layout. (#1760)box.widthwrite with a flush takes 111 ns instead of 149 ns. A paint value that only native code rejects, such as an opacity above 1 passed tosetNativeScenePaint, fails at the next flush. See Rendering pipeline. (#1770)Codecreates two native objects instead of three. A highlight update no longer copies the style table or scans the object table. See Code. (#1768, #1775)onMouseScrollhandler of an ancestor still receive it. Text, Code, and Textarea treat Shift+wheel as sideways, and an editor's sideways step stops at its widest line. See ScrollBox. (#1761)wcwidth, so under tmux and screen ❤️ is still one cell too narrow, until OpenTUI selects the width method correctly. In classic Windows conhost, which gives VS15 its own cell, 53 of these symbols followed by VS15 are now one cell off. Some terminals draw a glyph wider than the one cell that they advance, so it covers the next character, extends into a blank cell, or is cut off; this comes from the terminal, not from the layout. See Text and terminal cells. (#1762)detectLinks()styles bare URLs withmarkup.link.labelfrom the newsyntaxStylecontext field and keeps their other attributes. Bare URLs in Markdown prose now look like link labels. See Markdown. (#1765)maxProbeBytesrejects with the decoder error. Before, it could play a truncated prefix and end without an error. See Streaming audio. (#1759)CSI g, DECRQM, and other controls now behave as in xterm. XTGETTCAP answers from Ghostty's terminfo, which claims some features that the embedded terminal does not draw. See Embedded terminal. (#1714)OT_STYLE_RUN_FLAGbit, and user highlights reject such style ids. Styled text no longer registerschunkNstyles in the attachedSyntaxStyle, andot_text_buffer_clearwithout reset keeps styled highlights but drops their links. The styled-text batch accepts buffers that have an attached style. See Editing buffers and views. (#1768)ot_editor_view_get_viewport,ot_editor_view_set_scroll_margin, and a localot_editor_view_selectcan lay out text and returnOT_OUT_OF_MEMORY. This occurs only while a scroll to the cursor is pending. See C. (#1751)ot_scene_set_paintrejects a translation that is not finite or exceedsFLT_MAX,ot_scene_set_stylestores finite margin, padding, position, and gap values beyond ±1e30 as ±1e30, andOT_LAYOUT_PAINTclamps an axis outside the 32-bit cell range. See C. (#1682)Fixed
yoga.tsAPI keeps the upstream rounding. See Layout. (#1728)left = 2 ** 31 - 1ormargin = 1e15, no longer makes every later frame fail withInvalidArgument. Native code clamps only the geometry that it paints, clips, and hit-tests. See Layout. (#1682)wcwidthwidth method,drawTextandencodeUnicodegive a multi-code-point cluster, such as 👩💻, the same width as the layout. Before, text after the cluster landed two cells to the left. Clusters wider than four cells, such as 👨👩👧, are still drawn too narrow. See Text and terminal cells. (#1773)ScrollBarposition is never negative. Before, a ScrollBox with content that fit the viewport could report ascrollToporscrollLeftsuch as -7 while its content did not move. A ScrollBar'sonChangevalue andscrollPositionnow agree, and with sticky bottom over short content, a sideways scroll no longer stops the box from following new content. See ScrollBar. (#1769)destroy()leaves raw mode after the Session restores the terminal, andresume()enters raw mode before mouse reporting starts again. Before, mouse reports could show as text such as `^[[<35;30;5MConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.