Repository navigation
Conversation
Store retained output as lines so counts are constant-time and reads and searches avoid splitting the full buffer. Trim discarded lines in one batch and find the exit-notification tail with a single read. Normalize negative read and search offsets, including the tool's next-page hint. Intentional contract changes: honor PTY_MAX_BUFFER_LINES alongside PTY_MAX_BUFFER_SIZE, retaining whole lines until either limit is reached; only a single oversized line is sliced to its tail. Report byteLength as UTF-8 bytes instead of UTF-16 code units. Remove the exported no-op RingBuffer.flush(). Invalid or non-positive limits fall back to the existing defaults. An oversized final line that ends with a newline stays visible to pty_read and exit notifications. Reads use native slice pagination, and the line-density explanation lives in the README rather than the tool prompt.
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.
Summary
RingBuffersplits the whole buffer string every time its length, a read or a search is needed, never reads the documentedPTY_MAX_BUFFER_LINES, cuts the oldest line in the middle when it trims, and reports UTF-16 units as bytes. This PR stores output as lines and makes both documented limits work.In plain terms: the plugin keeps the latest output of each terminal so the agent can read it back. That storage redid a lot of work for every new chunk of output, which slowed down commands that print a lot, and one of the two documented size limits was never applied. Now it keeps output line by line, which is much faster, and both limits work as the README describes.
Problems fixed
length,read()andsearch()each runsplit('\n')over the full buffer, and the exit notification looks for its last line with oneread()per line. Feeding 16 MiB in 4,096 character chunks and readinglengthafter each chunk takes 1,616 ms on main (median of three runs) and 16 ms here.PTY_MAX_BUFFER_LINESis documented in the README and in thepty_readdescription, but nothing reads it.PTY_MAX_BUFFER_SIZEis read but not documented.line1\nline2\nline3\nline4leftine3\nline4; it now leavesline4.byteLengthreturnsbuffer.length, which counts UTF-16 code units: 3 forá😀, whose UTF-8 size is 6.OutputManager.readwith an offset below zero returned that offset andhasMore: trueon a ten line buffer, and the next page hint that search prints was built from the unclamped value.Changes
slice.byteLengthcounts UTF-8 bytes.RingBuffer.flush()was an exported no-op. It is removed together with its only caller.PTY_MAX_BUFFER_SIZEand how the two limits interact, and thepty_readdescription names both.Behavior changes
src/plugin/pty/tools/read.txt. This PR edits the line of that file that describes the limits, so whichever of the two lands second needs a small manual merge.Validation
Four new tests and one rewritten test cover the line limit, whole line trimming, the tail of an oversized line, UTF-8 byte length and negative offsets. All of them fail on main except the oversized line test, which passes on both and guards the new trimming. Removing the offset clamp makes its test fail again.
bun testovertest/*.test.ts, without the live and npm-pack suites, gives 188 passing.bun run typecheck,bun run lintandbunx biome format .are clean. I did not run the Playwright e2e suite locally. The only e2e assertion that comparesbyteLengthwith the raw length uses ASCII output, where both values still match.Benchmark script
Runs on main: 1,684 / 1,616 / 1,495 ms. Runs here: 18.9 / 16.1 / 15.2 ms.
Diff
Production: -13 lines (+43/-56) across
buffer.ts,notification-manager.ts,output-manager.ts,session-lifecycle.tsandtools/read.ts.Tests: +37 lines.
Docs: +3 lines (
README.md,tools/read.txt).