fix: keep chat output in the originating note when switching notes mid-stream - #206
Open
Vokinloksar wants to merge 1 commit into
Open
Conversation
…d-stream Obsidian reuses a single editor instance per tab and swaps its document when the user navigates to a different note in the same tab. The chat command captured that live editor at invocation but wrote to it asynchronously while streaming, so prompting in note A and then switching the tab to note B caused the response (and the trailing user delimiter / inferred title) to land in note B. Pin all output to the file captured when the command was invoked: - Add getFileForEditor() to detect which file an editor currently displays. - StreamingHandler verifies the editor still shows the original note before each write; once the user navigates away it sticky-redirects remaining output to the original file via app.vault.process() (ordered append queue), while live streaming is unchanged when the note stays active. - AiProviderService threads the originating app/file through the streaming path and only touches the editor (cursor, error text, tool notices) when it still shows the target note. - MessageService appends the trailing user delimiter to the original file when the editor has navigated away. - Title inference renames the captured file instead of whatever note is currently active. Add StreamingHandler tests covering on-target writes, redirect-on-switch, and sticky redirect. Import jest in the obsidian test mock (the new runtime obsidian import surfaced an ESM module-scope reference). Co-authored-by: Cursor <cursoragent@cursor.com>
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
Fixes a bug where streaming a chat response in note A and then switching the
tab to note B caused the response to be written into note B instead of note A.
Root cause: Obsidian reuses a single editor instance per tab and swaps its
document when you navigate to another note in the same tab. The chat command
captured that live editor at invocation but wrote to it asynchronously during
streaming, so once the tab switched notes, all subsequent output (and the
trailing user delimiter / inferred title) landed in the wrong note.
Changes
getFileForEditor()to detect which file an editor currently displays.StreamingHandlerverifies the editor still shows the original note beforeeach write. Once the user navigates away, it sticky-redirects remaining
output to the original file via
app.vault.process()(ordered append queue).Live streaming is unchanged while the note stays active.
AiProviderServicethreads the originating app/file through the streamingpath and only touches the editor (cursor, error text, tool notices) when it
still shows the target note.
MessageServiceappends the trailingrole::userdelimiter to the originalfile when the editor has navigated away.
currently active (same bug class).
jestin the obsidian test mock (the new runtimeobsidianimportsurfaced an ESM module-scope reference).
Note
The one edge case: if you switch notes mid-stream while in at-cursor mode, the redirected text is appended to the end of the original file rather than at the old cursor position. That's intentional —
once the note isn't in the visible editor, the cursor/selection no longer exists, so end-of-file append is the only safe option. The alternative (writing at a stale cursor in a hidden document) is
exactly the corruption we're fixing.
Test plan
yarn test— 120 passing (addedStreamingHandlertests coveringon-target writes, redirect-on-switch, and sticky redirect)
yarn build— type-check + production bundle succeedyarn lint— no new errorsstays in note A; note B untouched; reopening A shows the full response.