fix(breakpoints): clear the provisional message once a breakpoint verifies - #476
Conversation
…ifies js-debug answers setBreakpoints from its pending-target stub with a provisional message meaning 'Unbound breakpoint', and nothing cleared it after the breakpoint bound. list_breakpoints then reported verified:true and adapterId alongside a message asserting the opposite. The message also arrived as a raw l10n bundle key, because L10N_FSPATH_TO_BUNDLE is unset in the adapter spawn and l10n.t(key, fallback) returns the key verbatim. normalizeBreakpointMessage drops a provisional note when verified is true and otherwise resolves known js-debug keys to the English fallback declared at their call site, so no bundle key reaches the user. Applied at both places that stamp an adapter message onto a stored breakpoint. Closes debugmcp#471
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…ries no message Live verification of the repro showed the provisional message is stamped while the breakpoint is still unverified (so it is stored in translated form, "Unbound breakpoint"), and js-debug's later bind event flips verified:true without a message field — leaving the stale note in place, now in English instead of as a raw key. Two amendments: - Treat the translated fallback text as provisional too, since that is the form actually stored when stamping happens pre-verification. - Re-normalize the stored message when an update carries none, at both stamp sites, so verification clears a stale provisional note while real messages (source-map notes, capability-drift warnings) pass through untouched. Verified against the issue debugmcp#471 repro: list_breakpoints now reports verified:true, adapterId set, and no message field at all. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thank you — this is an outstanding first contribution. The analysis was exactly right on both counts: the two stamp sites (the #439 reconciliation path and the breakpoint-event path js-debug actually uses), and the l10n-key mechanism. The PR body alone saved a lot of review time. Before merging I ran the literal #471 repro against your branch, and it surfaced one subtle gap I've fixed with a commit pushed to your branch (15af266 — hope you don't mind, we're bundling this for the 0.25.0 release):
The amendment keeps your helper and applies it slightly more aggressively: the translated fallback text counts as provisional too, and both stamp sites re-normalize the stored message when an update carries none. Re-verified against the repro: On your two environment notes — both appreciated:
Will merge once CI is green. Thanks again — contributions at this level of care are very welcome here. |
Closes #471.
Both halves of the issue, fixed at the point where an adapter message is stamped onto a stored breakpoint.
1. Stale state. The provisional message was never cleared once the breakpoint verified, so
list_breakpointsassertedverified: true+adapterIdalongside a message meaning "Unbound breakpoint".2. Raw l10n key. The string arrived as a bundle key rather than text, since
L10N_FSPATH_TO_BUNDLEis unset in the adapter spawn andl10n.t(key, fallback)then returns the key verbatim.normalizeBreakpointMessage(message, verified)insrc/utils/breakpoint-message.tsdrops a provisional note whenverifiedis true, and otherwise resolves known js-debug keys to the English fallback declared at their ownl10n.tcall site. So the field either says something true or says nothing — and a leaked key never reaches the user either way.Applied at both stamp sites, not just one. The issue points at the #439 reconciliation path, but that is only half of it: the comment at
session-manager-core.ts:823notes js-debug's worker path never emitsbreakpoints_synced, so for JavaScript the message actually lands via thebreakpointevent handler. Fixing only the #439 path would have left the reported repro untouched. Both now go through the same helper.Test —
tests/unit/utils/breakpoint-message.test.ts, including the assertion the issue suggests (a verified breakpoint must not carry abreakpoint.key):Against
mainthe same suites give 3200 passed with an identical 3 failures, all in the dotnet adapter and unrelated to this change — so this PR adds 5 passing tests and no failures.Two environment notes, neither caused by this PR:
pnpm install --frozen-lockfilefails onmainwithERR_PNPM_LOCKFILE_CONFIG_MISMATCH(overrides drift), and thepostinstallCodeLLDB vendor step fails to fetch on this platform. I installed with--no-frozen-lockfileand deliberately revertedpnpm-lock.yamlso it is not part of the diff. Worth a look separately if you weren't aware.I did not touch the vendored
vsDebugServer.js— settingL10N_FSPATH_TO_BUNDLEat spawn time would fix the key at the source for all messages, but that is a larger change to adapter spawning and felt out of scope here. Happy to look at it if you'd prefer that direction.