Change:
a screen reader and run a few commands in the terminal up arrow and use the left arrow to navigate through the command the command text area is no longer synced correctly
what is the "text area"? I tried to repro the issue on stable and I looked at the accessible view, but I'm not sure what I'm looking for.
Enable "terminal.integrated.developer.devMode" to check the contents are right
Or use a screen reader and ensure that when navigating w arrow keys, the right chars are announced. In either case, need to be in screen reader optimized mode
Very cool to see this actually working for history

Discussion:
private _dimensions: ITerminalDimensions; private __isCommandStorageDisabled: boolean = false; private _handleCommandStartOptions?: IHandleCommandOptions; <ins> private _commandStartWindowsPromise?: Promise<void>; </ins> get commands(): readonly ITerminalCommand[] { return this._commands; } get executingCommand(): string | undefined { return this._currentCommand.command; }

return; } if (this._isWindowsPty) { <del> this._handleCommandStartWindows(); </del> <ins> this._commandStartWindowsPromise = this._handleCommandStartWindows(); </ins> return; } this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX;

this._logService.debug('CommandDetectionCapability#handleCommandStart', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line); } <del> private _handleCommandStartWindows(): void { </del> <ins> private async _handleCommandStartWindows(): Promise<void> { </ins> this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX; // On Windows track all cursor movements after the command start sequence this._commandMarkers.length = 0; <del> // HACK: Fire command started on the following frame on Windows to allow the cursor // position to update as conpty often prints the sequence on a different line to the // actual line the command started on. timeout(0).then(() => { if (!this._currentCommand.commandExecutedMarker) { this._onCursorMoveListener = this._terminal.onCursorMove(() => { if (this._commandMarkers.length === 0 || this._commandMarkers[this._commandMarkers.length - 1].line !== this._terminal.buffer.active.cursorY) { const marker = this._terminal.registerMarker(0); if (marker) { this._commandMarkers.push(marker); } } }); </del> <ins> const lastCommand = this.commands.at(-1); function cursorOnCorrectLine(terminal: Terminal): boolean { if (!lastCommand) { return false; </ins> } <del> this._currentCommand.commandStartMarker = this._terminal.registerMarker(0); if (this._currentCommand.commandStartMarker) { const line = this._terminal.buffer.active.getLine(this._currentCommand.commandStartMarker.line); if (line) { this._currentCommand.commandStartLineContent = line.translateToString(true); </del> <ins> const cursorYAbsolute = terminal.buffer.active.baseY + terminal.buffer.active.cursorY; // If the cursor position is within the last command, we should poll. const lastCommandYAbsolute = (lastCommand.endMarker ? lastCommand.endMarker.line : lastCommand.marker?.line) ?? -1; return cursorYAbsolute > lastCommandYAbsolute; } function lineIsPrompt(terminal: Terminal): boolean { const line = terminal.buffer.active.getLine(terminal.buffer.active.baseY + terminal.buffer.active.cursorY); if (!line) { return false; } // TODO: fine tune prompt regex to accomodate for unique configurtions. return line.translateToString(true)?.match(/^(PS.+>)|([A-Z]:.*>)/) !== null; } // Conpty could have the wrong cursor position at this point. if (!cursorOnCorrectLine(this._terminal) || !lineIsPrompt(this._terminal)) { // Poll for 200ms until the cursor position is correct. for (let i = 0; i < 20; i++) { await timeout(10); if (cursorOnCorrectLine(this._terminal) && lineIsPrompt(this._terminal)) { this._logService.debug('CommandDetectionCapability#_handleCommandStartWindows polling attempts required: ', i + 1); break; </ins> } } <del> this._onCommandStarted.fire({ marker: this._currentCommand.commandStartMarker } as ITerminalCommand); this._logService.debug('CommandDetectionCapability#_handleCommandStartWindows', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line); }); </del> <ins> } else { // HACK: Fire command started on the following frame on Windows to allow the cursor // position to update as conpty often prints the sequence on a different line to the // actual line the command started on. await timeout(0); } if (!this._currentCommand.commandExecutedMarker) { this._onCursorMoveListener = this._terminal.onCursorMove(() => { if (this._commandMarkers.length === 0 || this._commandMarkers[this._commandMarkers.length - 1].line !== this._terminal.buffer.active.cursorY) { const marker = this._terminal.registerMarker(0); if (marker) { this._commandMarkers.push(marker); } } }); } this._currentCommand.commandStartMarker = this._terminal.registerMarker(0); if (this._currentCommand.commandStartMarker) { const line = this._terminal.buffer.active.getLine(this._currentCommand.commandStartMarker.line); if (line) { this._currentCommand.commandStartLineContent = line.translateToString(true); } } this._onCommandStarted.fire({ marker: this._currentCommand.commandStartMarker } as ITerminalCommand); this._logService.debug('CommandDetectionCapability#_handleCommandStartWindows', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line); </ins> } handleGenericCommand(options?: IHandleCommandOptions): void {

handleCommandExecuted(options?: IHandleCommandOptions): void { if (this._isWindowsPty) { <del> this._handleCommandExecutedWindows(); </del> <ins> this._commandStartWindowsPromise?.then(() => this._handleCommandExecutedWindows()); </ins> return; }

handleCommandFinished(exitCode: number | undefined, options?: IHandleCommandOptions): void { if (this._isWindowsPty) { <del> this._preHandleCommandFinishedWindows(); </del> <ins> this._commandStartWindowsPromise?.then(() => this._preHandleCommandFinishedWindows()); </ins> } this._currentCommand.commandFinishedMarker = options?.marker || this._terminal.registerMarker(0);