Change:
changed to move to but this caused a feature for Codespaces to stop working where the terminal will start streaming in the init logs before the workbench has fully loaded. Ideally we would start it up on Starting only on remote, if we can't do that we need to move it back to Starting in the meantime. cc
We know if we are connected to a remote from the environment service via probing for .
We don't have access to services at workbench contrib registration do we?
no, but you could have 1 eager workbench contrib that depends on the environment service to decide if a second thing should get instantiated or not.
Marked verified, only can properly verify it
this seems to still be failing, the terminal does not show up until the codespace is fully created and the workbench initialized
Verified by

Discussion:
import { IStatusbarService } from 'vs/workbench/services/statusbar/browser/statusbar'; export class RemoteTerminalBackendContribution implements IWorkbenchContribution { <ins> static ID = 'remoteTerminalBackend'; </ins> constructor( @IInstantiationService instantiationService: IInstantiationService, @IRemoteAgentService remoteAgentService: IRemoteAgentService,

*--------------------------------------------------------------------------------------------*/ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; <ins> import { Schemas } from 'vs/base/common/network'; import { isIOS, isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; </ins> import 'vs/css!./media/scrollbar'; <del> import 'vs/css!./media/widgets'; import 'vs/css!./media/xterm'; </del> import 'vs/css!./media/terminal'; import 'vs/css!./media/terminalVoice'; <ins> import 'vs/css!./media/widgets'; import 'vs/css!./media/xterm'; </ins> import * as nls from 'vs/nls'; <del> import { URI } from 'vs/base/common/uri'; </del> <ins> import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; </ins> import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey'; <del> import { KeybindingWeight, KeybindingsRegistry, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { getQuickNavigateHandler } from 'vs/workbench/browser/quickaccess'; import { Extensions as ViewContainerExtensions, IViewContainersRegistry, ViewContainerLocation, IViewsRegistry } from 'vs/workbench/common/views'; </del> import { Extensions as DragAndDropExtensions, IDragAndDropContributionRegistry, IDraggedResourceEditorInput } from 'vs/platform/dnd/browser/dnd'; <del> import { registerTerminalActions, terminalSendSequenceCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView'; import { TERMINAL_VIEW_ID, TerminalCommandId, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; import { registerColors } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { setupTerminalCommands } from 'vs/workbench/contrib/terminal/browser/terminalCommands'; import { TerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ITerminalEditorService, ITerminalGroupService, ITerminalInstanceService, ITerminalService, TerminalDataTransfers, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal'; </del> import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; <del> import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; </del> <ins> import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IKeybindings, KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; </ins> import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess'; <del> import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess'; import { registerTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminalConfiguration'; import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { terminalViewIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons'; </del> <ins> import { Registry } from 'vs/platform/registry/common/platform'; </ins> import { ITerminalLogService, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; <del> import { isIOS, isWindows } from 'vs/base/common/platform'; import { setupTerminalMenus } from 'vs/workbench/contrib/terminal/browser/terminalMenus'; import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; </del> <ins> import { TerminalLogService } from 'vs/platform/terminal/common/terminalLogService'; </ins> import { registerTerminalPlatformConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; <del> import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor'; </del> import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; <ins> import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { getQuickNavigateHandler } from 'vs/workbench/browser/quickaccess'; import { WorkbenchPhase, registerWorkbenchContribution2 } from 'vs/workbench/common/contributions'; import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor'; import { IViewContainersRegistry, IViewsRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation } from 'vs/workbench/common/views'; import { RemoteTerminalBackendContribution } from 'vs/workbench/contrib/terminal/browser/remoteTerminalBackend'; import { ITerminalEditorService, ITerminalGroupService, ITerminalInstanceService, ITerminalService, TerminalDataTransfers, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalActions, terminalSendSequenceCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { setupTerminalCommands } from 'vs/workbench/contrib/terminal/browser/terminalCommands'; </ins> import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; <del> import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { TerminalEditorService } from 'vs/workbench/contrib/terminal/browser/terminalEditorService'; </del> import { TerminalInputSerializer } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer'; <ins> import { TerminalEditorService } from 'vs/workbench/contrib/terminal/browser/terminalEditorService'; </ins> import { TerminalGroupService } from 'vs/workbench/contrib/terminal/browser/terminalGroupService'; <del> import { TerminalContextKeys, TerminalContextKeyStrings } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { TerminalProfileService } from 'vs/workbench/contrib/terminal/browser/terminalProfileService'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { RemoteTerminalBackendContribution } from 'vs/workbench/contrib/terminal/browser/remoteTerminalBackend'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; </del> <ins> import { terminalViewIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons'; import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; </ins> import { TerminalMainContribution } from 'vs/workbench/contrib/terminal/browser/terminalMainContribution'; <del> import { Schemas } from 'vs/base/common/network'; import { TerminalLogService } from 'vs/platform/terminal/common/terminalLogService'; </del> <ins> import { setupTerminalMenus } from 'vs/workbench/contrib/terminal/browser/terminalMenus'; import { TerminalProfileService } from 'vs/workbench/contrib/terminal/browser/terminalProfileService'; import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess'; import { TerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView'; import { ITerminalProfileService, TERMINAL_VIEW_ID, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { registerColors } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { registerTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminalConfiguration'; import { TerminalContextKeyStrings, TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; </ins> // Register services registerSingleton(ITerminalLogService, TerminalLogService, InstantiationType.Delayed);

CommandsRegistry.registerCommand({ id: quickAccessNavigatePreviousInTerminalPickerId, handler: getQuickNavigateHandler(quickAccessNavigatePreviousInTerminalPickerId, false) }); // Register workbench contributions <del> const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(TerminalMainContribution, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(RemoteTerminalBackendContribution, LifecyclePhase.Restored); </del> <ins> // This contribution blocks startup as it's critical to enable the web embedder window.createTerminal API registerWorkbenchContribution2(TerminalMainContribution.ID, TerminalMainContribution, WorkbenchPhase.BlockStartup); registerWorkbenchContribution2(RemoteTerminalBackendContribution.ID, RemoteTerminalBackendContribution, WorkbenchPhase.AfterRestored); </ins> // Register configurations registerTerminalPlatformConfiguration();

import { parseTerminalUri } from 'vs/workbench/contrib/terminal/browser/terminalUri'; import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; <ins> import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; </ins> import { IEmbedderTerminalService } from 'vs/workbench/services/terminal/common/embedderTerminalService'; /**

* be more relevant). */ export class TerminalMainContribution extends Disposable implements IWorkbenchContribution { <ins> static ID = 'terminalMain'; </ins> constructor( @IEditorResolverService editorResolverService: IEditorResolverService, @IEmbedderTerminalService embedderTerminalService: IEmbedderTerminalService, <ins> @IWorkbenchEnvironmentService workbenchEnvironmentService: IWorkbenchEnvironmentService, </ins> @ILabelService labelService: ILabelService, <ins> @ILifecycleService lifecycleService: ILifecycleService, </ins> @ITerminalService terminalService: ITerminalService, @ITerminalEditorService terminalEditorService: ITerminalEditorService, @ITerminalGroupService terminalGroupService: ITerminalGroupService,

) { super(); <ins> this._init( editorResolverService, embedderTerminalService, workbenchEnvironmentService, labelService, lifecycleService, terminalService, terminalEditorService, terminalGroupService, terminalInstanceService ); } private async _init( editorResolverService: IEditorResolverService, embedderTerminalService: IEmbedderTerminalService, workbenchEnvironmentService: IWorkbenchEnvironmentService, labelService: ILabelService, lifecycleService: ILifecycleService, terminalService: ITerminalService, terminalEditorService: ITerminalEditorService, terminalGroupService: ITerminalGroupService, terminalInstanceService: ITerminalInstanceService ) { // Defer this for the local case only. This is important for the // window.createTerminal web embedder API to work before the workbench // is loaded on remote if (workbenchEnvironmentService.remoteAuthority === undefined) { await lifecycleService.when(LifecyclePhase.Restored); } this._register(embedderTerminalService.onDidCreateTerminal(async embedderTerminal => { const terminal = await terminalService.createTerminal({ config: embedderTerminal, location: TerminalLocation.Panel }); terminalService.setActiveInstance(terminal); await terminalService.revealActiveTerminal(); })); await lifecycleService.when(LifecyclePhase.Restored); </ins> // Register terminal editors <del> editorResolverService.registerEditor( </del> <ins> this._register(editorResolverService.registerEditor( </ins> `${Schemas.vscodeTerminal}:/**`, { id: terminalEditorId,

}; } } <del> ); </del> <ins> )); </ins> // Register a resource formatter for terminal URIs <del> labelService.registerFormatter({ </del> <ins> this._register(labelService.registerFormatter({ </ins> scheme: Schemas.vscodeTerminal, formatting: { label: '${path}', separator: '' } <del> }); embedderTerminalService.onDidCreateTerminal(async embedderTerminal => { const terminal = await terminalService.createTerminal({ config: embedderTerminal, location: TerminalLocation.Panel }); terminalService.setActiveInstance(terminal); await terminalService.revealActiveTerminal(); }); </del> <ins> })); </ins> } }