Added clipboard read and paste support to core input handling#1939
Added clipboard read and paste support to core input handling#1939Srushti-Thombre wants to merge 6 commits into
Conversation
📝 WalkthroughWalkthroughThe PR updates ChangesDependency updates
Input parser refactor
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates @termuijs/core input parsing to better handle terminal bracketed paste mode, aiming to reliably emit paste events when paste start/end markers and pasted content arrive across multiple input chunks. It also adds a regression test around chunk-splitting behavior and adjusts the core package TS config to include Node types.
Changes:
- Add paste-collection state (
_isPasting/_pasteBuffer) so bracketed paste text can span multiple stdin chunks. - Ensure non-paste input before/after a paste sequence is still processed normally.
- Add a regression test for multi-chunk bracketed paste, and update core tsconfig to include Node ambient types.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/core/tsconfig.json | Adds Node ambient types for the core package compilation context. |
| packages/core/src/input/InputParser.ts | Refactors bracketed paste handling into a stateful collector to support multi-chunk pastes. |
| packages/core/src/input/InputParser.test.ts | Adds a regression test to validate bracketed paste behavior across chunks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for the contribution. There are issues to fix before this merges. Issues:
Checklist before re-requesting review:
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/core/src/input/InputParser.ts (2)
132-149: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winPaste timeout is never started — an incomplete paste permanently wedges the parser.
_startPasteTimeout()/_clearPasteTimeout()(lines 279–293) are defined but never called anywhere. When aPASTE_STARTmarker arrives without a matchingPASTE_END,_isPastingis set totrueand staystrueforever: every subsequentdatachunk falls into theif (this._isPasting)branch at Line 132 and is silently appended to_pasteBuffer, so no further key/mouse/escape events are ever emitted.The "recovers from partial paste via timeout" test passes only because it asserts the handler was not called; it never verifies that normal input resumes after the 500ms window, so the regression is masked.
Start the timeout when entering/continuing a paste and clear it on completion.
🔒️ Wire up the paste timeout
if (this._isPasting) { this._pasteBuffer += str; + this._startPasteTimeout(); this._finishPasteIfComplete(PASTE_END); return; } @@ this._isPasting = true; this._pasteBuffer = str.slice(pasteStartIndex + PASTE_START.length); + this._startPasteTimeout(); this._finishPasteIfComplete(PASTE_END); return; }And clear it on successful completion in
_finishPasteIfComplete:this._isPasting = false; this._pasteBuffer = ''; + this._clearPasteTimeout(); this._events.emit('paste', pastedText);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/input/InputParser.ts` around lines 132 - 149, The paste handling in InputParser can get stuck because `_startPasteTimeout()` is never invoked when `_isPasting` becomes true, so an incomplete paste leaves the parser permanently wedged. Update `InputParser` so the timeout is started when entering or continuing paste mode in the `data` handling path, and make sure `_clearPasteTimeout()` is called when `_finishPasteIfComplete()` successfully ends a paste. Verify the logic around `_isPasting`, `_pasteBuffer`, `_startPasteTimeout`, and `_finishPasteIfComplete` so normal input resumes after the timeout if `PASTE_END` never arrives.
128-133: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMultibyte bracketed paste can still be corrupted
_processInput()decodes paste chunks withdata.toString('utf8'), so a UTF-8 code point split across chunks turns intoU+FFFDbefore it reaches_pasteBuffer. Use the existingStringDecoderpath here, or buffer raw bytes untilPASTE_ENDand decode once.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/input/InputParser.ts` around lines 128 - 133, In InputParser._processInput(), bracketed paste handling is still decoding each chunk with data.toString('utf8'), which can corrupt split UTF-8 characters before they reach _pasteBuffer. Update the paste path to use the existing StringDecoder-based flow, or keep raw bytes buffered until PASTE_END and decode once at the end, so multibyte characters survive chunk boundaries intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Line 46: The optional peer dependency error in the dotenv adapter still
references the old supported range, so update the missing-dependency message in
packages/adapters/src/dotenv/index.ts to match the new workspace range for
dotenv. Adjust the text in the logic that throws from the dotenv adapter’s parse
path so it points users to install dotenv@^17.4.2 instead of dotenv@^16.0.0,
keeping the rest of the error wording consistent.
---
Outside diff comments:
In `@packages/core/src/input/InputParser.ts`:
- Around line 132-149: The paste handling in InputParser can get stuck because
`_startPasteTimeout()` is never invoked when `_isPasting` becomes true, so an
incomplete paste leaves the parser permanently wedged. Update `InputParser` so
the timeout is started when entering or continuing paste mode in the `data`
handling path, and make sure `_clearPasteTimeout()` is called when
`_finishPasteIfComplete()` successfully ends a paste. Verify the logic around
`_isPasting`, `_pasteBuffer`, `_startPasteTimeout`, and `_finishPasteIfComplete`
so normal input resumes after the timeout if `PASTE_END` never arrives.
- Around line 128-133: In InputParser._processInput(), bracketed paste handling
is still decoding each chunk with data.toString('utf8'), which can corrupt split
UTF-8 characters before they reach _pasteBuffer. Update the paste path to use
the existing StringDecoder-based flow, or keep raw bytes buffered until
PASTE_END and decode once at the end, so multibyte characters survive chunk
boundaries intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: de1a24b6-74c2-44d2-a862-73a7ada15af8
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (2)
package.jsonpackages/core/src/input/InputParser.ts
| "dependencies": { | ||
| "commander": "^15.0.0", | ||
| "dotenv": "^16.0.0" | ||
| "dotenv": "^17.4.2" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Update stale error message referencing dotenv@^16.0.0.
This bumps the workspace's dotenv range to ^17.4.2, but packages/adapters/src/dotenv/index.ts still tells users to Install dotenv@^16.0.0 in its "missing optional peer dependency" error. Since only dotenv.parse() is used, the major bump itself looks safe, but the error text should match the now-supported range.
💬 Suggested fix in packages/adapters/src/dotenv/index.ts
- 'useDotenv() requires the optional peer dependency `dotenv`. Install `dotenv@^16.0.0` in your app before calling useDotenv().'
+ 'useDotenv() requires the optional peer dependency `dotenv`. Install `dotenv@^17.4.2` in your app before calling useDotenv().'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` at line 46, The optional peer dependency error in the dotenv
adapter still references the old supported range, so update the
missing-dependency message in packages/adapters/src/dotenv/index.ts to match the
new workspace range for dotenv. Adjust the text in the logic that throws from
the dotenv adapter’s parse path so it points users to install dotenv@^17.4.2
instead of dotenv@^16.0.0, keeping the rest of the error wording consistent.
Description
This PR fixes bracketed paste handling in
@termuijs/coreso pasted text is collected correctly even when the start and end markers arrive in separate input chunks. It also keeps any trailing input after the paste marker working normally, and adds a regression test for the split-chunk case.Related Issue
Closes #1619
Which package(s)?
@termuijs/core
Type of Change
type:bug)type:feature)type:docs)type:testing)type:refactor)type:design)type:accessibility)type:performance)type:devops)type:security)Checklist
needs-starcheck blocks your merge otherwise.bun vitest runbun run buildbun run typecheckCONTRIBUTING.md.type: short description.markDirty()(if your change affects rendering).anytypes without an inline comment explaining why.GSSoC 2026 Participation
https://gssoc.girlscript.org/profile/a59d754a-8095-4997-91d8-2fb4c1577efaScreenshots / Recordings (UI changes)
Notes for the Reviewer
I validated the touched package with:
bunx vitest run packages/core/src/input/InputParser.test.tsbunx tsc -p packages/core/tsconfig.json --noEmitbun run typecheckand the full test/build pipeline currently fail for unrelated existing issues inpackages/testing,packages/jsx, andpackages/adapters(resetHooksGlobals,invalidateLayout, and optionaldotenvresolution). Those failures are not caused by this clipboard/paste change.The repo-wide
bun run buildandbun run typecheckwere not run in this session.Summary by CodeRabbit