@@ -538,7 +538,7 @@ const mergeEnv = (
538538 }
539539 merged [ pathKey ] = segments . join ( path . delimiter ) ;
540540 logger . debug (
541- `Augmented PATH for diagnostic capture with ${ binDirs . length } node_modules/.bin directorie (s).`
541+ `Augmented PATH for diagnostic capture with ${ binDirs . length } node_modules/.bin directories (s).`
542542 ) ;
543543 }
544544 return merged ;
@@ -1274,6 +1274,7 @@ export const startDebuggingAndWaitForStop = async (
12741274 const validated : Array < {
12751275 bp : ( typeof breakpointConfig . breakpoints ) [ number ] ;
12761276 sb : vscode . SourceBreakpoint ;
1277+ resolvedLine : number ;
12771278 } > = [ ] ;
12781279 for ( const bp of breakpointConfig . breakpoints ) {
12791280 const absolutePath = path . isAbsolute ( bp . path )
@@ -1312,7 +1313,7 @@ export const startDebuggingAndWaitForStop = async (
13121313 effectiveHitCondition ,
13131314 adapterLogMessage
13141315 ) ;
1315- validated . push ( { bp, sb : sourceBp } ) ;
1316+ validated . push ( { bp, sb : sourceBp , resolvedLine : bp . line } ) ;
13161317 } catch ( e ) {
13171318 logger . error (
13181319 `Failed to open file for breakpoint path ${ absolutePath } : ${
@@ -1321,6 +1322,34 @@ export const startDebuggingAndWaitForStop = async (
13211322 ) ;
13221323 }
13231324 }
1325+ const updateResolvedBreakpointLine = ( source : vscode . SourceBreakpoint ) => {
1326+ const match = validated . find ( ( entry ) => entry . sb === source ) ;
1327+ if ( ! match ) {
1328+ return ;
1329+ }
1330+ const nextResolvedLine = source . location . range . start . line + 1 ;
1331+ if ( match . resolvedLine === nextResolvedLine ) {
1332+ return ;
1333+ }
1334+ logger . debug (
1335+ `Breakpoint ${ source . location . uri . fsPath } resolved line changed from ${ match . resolvedLine } to ${ nextResolvedLine } .`
1336+ ) ;
1337+ match . resolvedLine = nextResolvedLine ;
1338+ } ;
1339+ let breakpointChangeDisposable : vscode . Disposable | undefined ;
1340+ if ( validated . length ) {
1341+ breakpointChangeDisposable = vscode . debug . onDidChangeBreakpoints (
1342+ ( event ) => {
1343+ const candidates = [ ...event . added , ...event . changed ] . filter (
1344+ ( bp ) : bp is vscode . SourceBreakpoint =>
1345+ bp instanceof vscode . SourceBreakpoint
1346+ ) ;
1347+ for ( const bp of candidates ) {
1348+ updateResolvedBreakpointLine ( bp ) ;
1349+ }
1350+ }
1351+ ) ;
1352+ }
13241353 // Optional serverReady breakpoint (declare early so scope is available later)
13251354 let serverReadySource : vscode . SourceBreakpoint | undefined ;
13261355 if (
@@ -1898,10 +1927,10 @@ export const startDebuggingAndWaitForStop = async (
18981927 const isServerReadyHit =
18991928 ! ! serverReadySource && entryStop . line === serverReady ?. trigger ?. line ;
19001929 // Decide whether to continue immediately (entry not at user breakpoint OR serverReady hit)
1901- const entryLineZeroBased = entryStop . line ? entryStop . line - 1 : - 1 ;
1902- const hitRequestedBreakpoint = validated . some (
1903- ( v ) => v . sb . location . range . start . line === entryLineZeroBased
1904- ) ;
1930+ const entryLineOneBased = entryStop . line ?? - 1 ;
1931+ const hitRequestedBreakpoint =
1932+ entryLineOneBased > 0 &&
1933+ validated . some ( ( v ) => v . resolvedLine === entryLineOneBased ) ;
19051934 logger . info (
19061935 `EntryStop diagnostics: line=${ entryStop . line } serverReadyLine=${ serverReady ?. trigger ?. line } isServerReadyHit=${ isServerReadyHit } hitRequestedBreakpoint=${ hitRequestedBreakpoint } `
19071936 ) ;
@@ -2081,24 +2110,26 @@ export const startDebuggingAndWaitForStop = async (
20812110 const frameLine = debugContext . frame ?. line ;
20822111 if ( framePath && typeof frameLine === "number" ) {
20832112 const normalizedFramePath = normalizeFsPath ( framePath ) ;
2084- for ( const { bp } of validated ) {
2113+ for ( const { bp, resolvedLine } of validated ) {
20852114 const absPath = path . isAbsolute ( bp . path )
20862115 ? bp . path
20872116 : path . join ( folderFsPath , bp . path ) ;
2088- if (
2089- normalizeFsPath ( absPath ) === normalizedFramePath &&
2090- bp . line === frameLine
2091- ) {
2092- hitBreakpoint = {
2093- path : absPath ,
2094- line : bp . line ,
2095- variableFilter : bp . variableFilter ,
2096- action : bp . action ,
2097- logMessage : bp . logMessage ,
2098- reasonCode : bp . reasonCode ,
2099- } ;
2100- break ;
2117+ if ( normalizeFsPath ( absPath ) !== normalizedFramePath ) {
2118+ continue ;
2119+ }
2120+ const matchesLine = frameLine === bp . line || frameLine === resolvedLine ;
2121+ if ( ! matchesLine ) {
2122+ continue ;
21012123 }
2124+ hitBreakpoint = {
2125+ path : absPath ,
2126+ line : frameLine ,
2127+ variableFilter : bp . variableFilter ,
2128+ action : bp . action ,
2129+ logMessage : bp . logMessage ,
2130+ reasonCode : bp . reasonCode ,
2131+ } ;
2132+ break ;
21022133 }
21032134 }
21042135 // Build variable lookup for interpolation (for capture action log message expansion)
@@ -2251,6 +2282,7 @@ export const startDebuggingAndWaitForStop = async (
22512282 activeDebugPatternScan = undefined ;
22522283 terminalCapture . dispose ( ) ;
22532284 taskStartDisposable ?. dispose ( ) ;
2285+ breakpointChangeDisposable ?. dispose ( ) ;
22542286 // Restore original breakpoints, removing any added ones first
22552287 const current = vscode . debug . breakpoints ;
22562288 if ( current . length ) {
0 commit comments