fix(bridge): carry external rewrites of open files through the reused tsserver program (#74) - #75
Merged
johnsoncodehk merged 3 commits intoSep 26, 2026
Conversation
… tsserver program (#74) tsserver keeps a thin program across updateOpen/reload (__tnbIsProgramUptoDate), so its steady-state sync is pushHostOverlayToTsgo, which never drained the #49 external-change set: a host==disk rewrite skipped the overlay push and Go kept its first-read text. Semantic classifications landed at the old offsets and diagnostics went stale. Both updateSnapshot sites now drain through drainExternalFileChanges and send host==disk files as fileChanges.changed, and TextStorage.reloadWithFileText (tsserver reload) raises the same signal as reloadForOpen. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
…n triage-external-edits (#74) The tsserver case now runs once per client re-sync (reopen, changedFiles, reload) and compares the rewritten file's semantic classifications with stock, alongside the dependent-file diagnostic. On 6.0.3-bridge.17, changedFiles and reload fail. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
…NB at the commit under test Rewriting volar's typescript override to link: the workspace made pnpm re-resolve every `latest` specifier from scratch. vitest 5.0.2 (published 2026-09-25) pulls why-is-node-running@3.2.2, which pnpm 11's trustPolicy rejects as a trust downgrade, so every cache-miss build failed at 'Install + build volar' — the v4 cache had been evicted, so this hit every run. tools/install-volar.sh is now the one recipe (ci.yml, nightly.yml, AGENTS.md): frozen install of volar's vetted lockfile, the released TNB's store entries symlinked to this repo, and the release's platform bridges deleted — they resolve ahead of <repo>/native and would pair this commit's JS with the pinned release's bridge.node. Cache keys bumped (v5, nightly-v3) for the new tree layout. Co-authored-by: Johnson Chu <johnsoncodehk@users.noreply.github.com>
johnsoncodehk
marked this pull request as ready for review
September 26, 2026 03:31
johnsoncodehk
deleted the
cursor/issue-74-query-sync-external-changes-a06b
branch
September 26, 2026 03:31
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.
Fixes #74.
Root cause
Under tsserver,
__tnbIsProgramUptoDatekeeps the thin program acrossupdateOpenandreload.createTsgoProgram's overlay collect therefore never reruns, and the only sync is the query-pathpushHostOverlayToTsgo. That function never drained the #49 external-change set (_pendingExternalChangePaths). When an external tool rewrote an open file and the editor re-synced the buffer to the new disk text:shouldSendHostOverlayskipped it,fileChanges.changedwas sent, so the no-change fast path returned with noupdateSnapshot,As a result, semantic classifications were returned at the old file's offsets, and diagnostics were stale too. For example, a new
const bad: string = 1error was missing.The
reloadcommand had a second gap:TextStorage.reloadWithFileTextnever raised the signal at all. OnlyreloadForOpenandeditContentdid.The existing #49 tsserver witness missed this because it re-sends through
openFiles, which goes throughreloadForOpen. It never exercisedchangedFilesorreload.Change
drainExternalFileChanges()is the single place that decides the transport. BothupdateSnapshotsites call it: thecreateTsgoProgramcollect andpushHostOverlayToTsgo. Host==disk files ridefileChanges.changed. The fast path no longer skips when there are external changes, and the per-file JS caches (tsgoSfCache, node indexes, host SourceFile) are invalidated for those files.reloadWithFileTextcallstnbNoteExternalFileChangewhen the text changed.triage-external-editstsserver case: runs once per client re-sync (reopen,changedFiles,reload) and compares the rewritten file'sencodedSemanticClassifications-fullspans with stock, plus the dependent-file diagnostic.No Go-side change, so no README ledger row.
Verification
Local runs used the fork bundle built from this branch plus the published 6.0.3-bridge.17
bridge.nodeandvendor/. The Go side is unchanged, and this VM has Go 1.22, not 1.26.run3.mjs(updateOpen/reload) plus achangecontrol:12 6 "文中文 上傳", …).typescript@6.0.3, andsemanticDiagnosticsSyncreports the new TS2322 like stock.triage-external-edits.tsserver: fails on bridge.17 forchangedFilesandreload; passes on this branch in all three modes.stablecache: passes.tscwatch: times out at watch block 2 on this VM for both bridge.17 and this branch, so it's environmental, not a regression.VOLAR_ROOTwas a local volar checkout atVOLAR_SHA, andsweep-ls-throwsreported 0 correlated throw hits.check:sim-nav. diffs baseline=1747 current=1747, new=0, fixed=0. The probed unit count went from 25122 to 25123, and the extra unit is a match.npm test: 211 passed, 4 skipped.check:sourcefile-guard,check:lib,check:enums,ci-witness-groups.mjs all: pass.