Skip to content

Terminal error NES prototype#323166

Open
6hl wants to merge 1 commit into
microsoft:mainfrom
6hl:6hl/terminal-error-nes
Open

Terminal error NES prototype#323166
6hl wants to merge 1 commit into
microsoft:mainfrom
6hl:6hl/terminal-error-nes

Conversation

@6hl

@6hl 6hl commented Jun 26, 2026

Copy link
Copy Markdown

No description provided.

Copilot AI review requested due to automatic review settings June 26, 2026 16:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an experimental “terminal error → Next Edit Suggestion (NES)” prototype to the Copilot extension by monitoring failed terminal shell executions, parsing file/line diagnostics from their output, enriching the Xtab NES prompt with those errors, and optionally triggering inline suggestions when a failure is observed.

Changes:

  • Introduces a terminal failure monitor (ITerminalMonitor/TerminalMonitor) that captures shell execution output, parses structured errors, and resolves them to workspace file URIs.
  • Enriches Xtab prompt construction with a new <|recent_terminal_errors|> block and forces PatchBased02 prompting strategy when terminal errors are present.
  • Adds an opt-in experiment setting github.copilot.nextEditSuggestions.fixesFromTerminal, plus a VS Code contribution that triggers inline suggestions after eligible terminal failures.
Show a summary per file
File Description
extensions/copilot/src/platform/test/node/simulationWorkspaceServices.ts Updates terminal test service surface to include the new shell-execution start event.
extensions/copilot/src/platform/terminal/vscode/terminalServiceImpl.ts Exposes VS Code’s window.onDidStartTerminalShellExecution through the terminal service impl.
extensions/copilot/src/platform/terminal/common/terminalService.ts Extends ITerminalService and null impl with onDidStartTerminalShellExecution.
extensions/copilot/src/platform/configuration/common/configurationService.ts Adds ConfigKey.InlineEditsFixesFromTerminal experiment key.
extensions/copilot/src/extension/xtab/test/common/terminalOutput.spec.ts Adds unit tests for resolving error file paths into workspace URIs.
extensions/copilot/src/extension/xtab/test/common/terminalErrorParser.spec.ts Adds unit tests for parsing diagnostics from multiple tool outputs.
extensions/copilot/src/extension/xtab/test/common/promptCrafting.spec.ts Extends prompt tests to cover terminal error formatting and postscript behavior.
extensions/copilot/src/extension/xtab/node/xtabProvider.ts Pulls recent terminal failures into prompt building and adjusts model strategy selection.
extensions/copilot/src/extension/xtab/common/terminalOutput.ts Implements terminal failure capture, parsing, workspace resolution, and emits failure events.
extensions/copilot/src/extension/xtab/common/terminalErrorParser.ts Adds regex-based parsing of common tool error formats into structured entries.
extensions/copilot/src/extension/xtab/common/tags.ts Introduces PromptTags.TERMINAL_ERRORS.
extensions/copilot/src/extension/xtab/common/promptCrafting.ts Adds terminal error block formatting and includes it in prompt assembly.
extensions/copilot/src/extension/test/node/services.ts Registers ITerminalMonitor for extension unit test DI.
extensions/copilot/src/extension/inlineEdits/vscode-node/terminalErrorNesTrigger.ts New contribution that opens the failing file and triggers inline suggestions (debounced).
extensions/copilot/src/extension/extension/vscode-node/services.ts Registers ITerminalMonitor in the main extension DI container.
extensions/copilot/src/extension/extension/vscode-node/contributions.ts Wires the new terminal-trigger contribution into the extension contributions list.
extensions/copilot/package.nls.json Adds localized description for fixesFromTerminal.
extensions/copilot/package.json Adds the github.copilot.nextEditSuggestions.fixesFromTerminal configuration property.

Review details

  • Files reviewed: 18/18 changed files
  • Comments generated: 8
  • Review effort level: Low

Comment on lines +118 to +125
// Drop any in-flight captures for executions on this terminal.
for (const execution of Array.from(this._pendingExecutionOutputs.keys())) {
// We can't ask the execution which terminal it belongs to once it
// has ended, so we conservatively keep entries until their own
// end event drains them; a closed terminal will simply leave us
// with at most one stale entry that the next end event clears.
void execution;
}
Comment on lines +137 to +144
for await (const chunk of execution.read()) {
const current = this._pendingExecutionOutputs.get(execution);
if (current === undefined) {
// The end handler already consumed and removed this entry.
return;
}
this._pendingExecutionOutputs.set(execution, current + chunk);
}
Comment on lines +129 to +133
private _beginCapturingExecution(execution: vscode.TerminalShellExecution): void {
// eslint-disable-next-line no-console
console.debug(`[TerminalMonitor] onDidStartTerminalShellExecution fired: commandLine=${execution.commandLine?.value ?? '<unknown>'}; begin read()`);
// Seed an empty string so the end handler can tell "we captured it"
// apart from "we never saw the start" (shell integration off).
Comment on lines +46 to +47
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] contribution constructed and listening for terminal failures`);
Comment on lines +116 to +121
} catch (err) {
this.logService.debug(`[TerminalErrorNesTrigger] showTextDocument failed for ${target.uri.toString()}: ${err instanceof Error ? err.message : String(err)}`);
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] showTextDocument failed for ${target.uri.toString()}: ${err instanceof Error ? err.message : String(err)}`);
return;
}
Comment on lines +144 to +148
} catch (err) {
this.logService.debug(`[TerminalErrorNesTrigger] selection probe failed: ${err instanceof Error ? err.message : String(err)}`);
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] selection probe failed: ${err instanceof Error ? err.message : String(err)}`);
}
Comment on lines +150 to +153
this.logService.debug(`[TerminalErrorNesTrigger] triggering inline suggest at ${target.uri.toString()}:${target.position.line + 1} (${errorCount} error(s) from \`${commandLine ?? '<unknown>'}\`)`);
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] triggering inline suggest at ${target.uri.toString()}:${target.position.line + 1} (${errorCount} error(s) from \`${commandLine ?? '<unknown>'}\`)`);
void vscode.commands.executeCommand('editor.action.inlineSuggest.trigger');
Comment on lines +49 to +66
this._register(terminalMonitor.onDidObserveTerminalFailure(failure => {
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] onDidObserveTerminalFailure received: errors=${failure.errors.length}, commandLine=${failure.commandLine ?? '<unknown>'}`);
if (!this.configService.getExperimentBasedConfig(ConfigKey.InlineEditsFixesFromTerminal, this.expService)) {
this.logService.debug(`[TerminalErrorNesTrigger] setting nextEditSuggestions.fixesFromTerminal is off, not triggering`);
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] setting nextEditSuggestions.fixesFromTerminal is off, not triggering`);
return;
}
const target = pickTriggerTarget(failure);
if (target === undefined) {
this.logService.debug(`[TerminalErrorNesTrigger] no resolvable error file in failure, not triggering`);
// eslint-disable-next-line no-console
console.debug(`[TerminalErrorNesTrigger] no resolvable error file in failure, not triggering`);
return;
}
this._scheduleTrigger(target, failure.errors.length, failure.commandLine);
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants