fix(cli): trim prompts before appPrompt dedupe match - #1750
Open
xiaojingyu812 wants to merge 1 commit into
Open
Conversation
The remote-mode JSONL scanner dedupes app-sent prompts by exact content match, but the SDK writes the prompt to the JSONL with a trailing newline while the app delivers it without one. The match misses and the scanner re-forwards the prompt, persisting the user's message twice on the server (observed on live sessions as duplicate consecutive user messages with identical text). Extract the ring buffer into appPromptDedupe.ts, trim on both record and consume, and add unit tests including the trailing-newline regression.
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.
Problem
In remote (daemon-spawned) sessions, every prompt sent from the app is persisted twice on the server: once by the app itself, and once again by the remote-mode JSONL scanner re-forwarding it.
Observed on live sessions (see my comment on #914 for the full investigation): decrypting the stored history shows two consecutive
role: 'user'messages with identical text — e.g.seq=9 "回复ok"(sentFrom: ios) andseq=14 "回复ok"(sentFrom: cli).Root cause
runClaude.tsdedupes app-sent prompts against the scanner by exact content match:recordAppPrompt()receives the app-delivered text:"回复ok"consumeAppPrompt()receives the JSONL-echoed text the SDK wrote:"回复ok\n"(trailing newline)The exact match misses, the scanner treats the prompt as terminal-typed, and forwards it again.
Fix
Extract the ring buffer into
appPromptDedupe.ts(behavior otherwise unchanged: 5-minute window, consume-once semantics, stale entries roll off) and trim on both record and consume so the comparison ignores the SDK's trailing newline. The existing empty-line guard in the scanner already uses trim semantics, so this is consistent with how "same prompt" is defined there.Tests
Six unit tests in
appPromptDedupe.test.ts, including the trailing-newline regression case and the 5-minute expiry window (vitest run src/claude/appPromptDedupe.test.ts→ 6/6 passing).