@codingame/monaco-vscode-workbench-service-override 37.3.3 → 37.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/package.json +10 -10
  2. package/session.js +11 -0
  3. package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.d.ts +18 -0
  4. package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.js +27 -0
  5. package/vscode/src/vs/sessions/browser/layoutActions.d.ts +1 -0
  6. package/vscode/src/vs/sessions/browser/layoutActions.js +146 -0
  7. package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.js +6 -6
  8. package/vscode/src/vs/sessions/browser/parts/chatGroupView.js +5 -5
  9. package/vscode/src/vs/sessions/browser/parts/menubar.contribution.js +8 -8
  10. package/vscode/src/vs/sessions/browser/parts/sessionHeader.js +1 -1
  11. package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.js +1 -1
  12. package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.js +20 -20
  13. package/vscode/src/vs/sessions/browser/sessionsSetUpService.js +7 -7
  14. package/vscode/src/vs/sessions/browser/sessionsSignInDialog.js +4 -4
  15. package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.js +42 -42
  16. package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.js +11 -11
  17. package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeView.contribution.js +18 -18
  18. package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.js +12 -12
  19. package/vscode/src/vs/sessions/contrib/applyCommitsToParentRepo/browser/applyChangesToParentRepo.d.ts +1 -0
  20. package/vscode/src/vs/sessions/contrib/applyCommitsToParentRepo/browser/applyChangesToParentRepo.js +149 -0
  21. package/vscode/src/vs/sessions/contrib/aquarium/browser/aquarium.contribution.js +12 -12
  22. package/vscode/src/vs/sessions/contrib/aquarium/browser/aquariumOverlay.js +10 -10
  23. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.js +68 -68
  24. package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.js +7 -7
  25. package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.js +4 -4
  26. package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.js +2 -2
  27. package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.js +38 -38
  28. package/vscode/src/vs/sessions/contrib/automations/browser/automations.contribution.js +2 -2
  29. package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.js +1 -1
  30. package/vscode/src/vs/sessions/contrib/changes/browser/changes.contribution.js +6 -6
  31. package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.js +4 -4
  32. package/vscode/src/vs/sessions/contrib/changes/browser/changesViewActions.js +20 -20
  33. package/vscode/src/vs/sessions/contrib/changes/browser/changesetReviewActions.js +1 -1
  34. package/vscode/src/vs/sessions/contrib/changes/browser/sessionSyncChanges.js +9 -9
  35. package/vscode/src/vs/sessions/contrib/changes/browser/sessionsChangesAccessibilityHelp.js +17 -17
  36. package/vscode/src/vs/sessions/contrib/chat/browser/sessionChatInputToolbarDebug.js +17 -17
  37. package/vscode/src/vs/sessions/contrib/chat/browser/taskCommand.d.ts +44 -0
  38. package/vscode/src/vs/sessions/contrib/chat/browser/taskCommand.js +111 -0
  39. package/vscode/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.js +2 -2
  40. package/vscode/src/vs/sessions/contrib/codeReview/browser/codeReview.contributions.d.ts +1 -0
  41. package/vscode/src/vs/sessions/contrib/codeReview/browser/codeReview.contributions.js +75 -0
  42. package/vscode/src/vs/sessions/contrib/customViewTest/browser/customViewTest.contribution.js +7 -7
  43. package/vscode/src/vs/sessions/contrib/editor/browser/addTabActions.js +4 -4
  44. package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.js +8 -8
  45. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.contribution.js +1 -1
  46. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.js +5 -5
  47. package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditorInput.js +1 -1
  48. package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.js +7 -7
  49. package/vscode/src/vs/sessions/contrib/files/browser/filesView.js +1 -1
  50. package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.js +5 -5
  51. package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.js +2 -2
  52. package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneExistingSessionStrategy.js +1 -1
  53. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3Prompt.js +19 -19
  54. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionTour.js +4 -4
  55. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTour.js +6 -6
  56. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.js +2 -2
  57. package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.js +4 -4
  58. package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.js +24 -24
  59. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.d.ts +26 -0
  60. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.js +98 -0
  61. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.d.ts +33 -0
  62. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.js +98 -0
  63. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostForkActions.d.ts +1 -0
  64. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostForkActions.js +72 -0
  65. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.d.ts +2 -0
  66. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.js +13 -0
  67. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.d.ts +122 -0
  68. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.js +464 -0
  69. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.d.ts +35 -0
  70. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.js +90 -0
  71. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.d.ts +84 -0
  72. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.js +328 -0
  73. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionBranchActions.d.ts +1 -0
  74. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionBranchActions.js +94 -0
  75. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.d.ts +174 -0
  76. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.js +1390 -0
  77. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentMergeActions.d.ts +1 -0
  78. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentMergeActions.js +468 -0
  79. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/exportDebugLogsAction.d.ts +7 -0
  80. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/exportDebugLogsAction.js +48 -0
  81. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/media/agentHostSessionConfigPicker.css +44 -0
  82. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.d.ts +30 -0
  83. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.js +78 -0
  84. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatInputConfigPicker.d.ts +1 -0
  85. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatInputConfigPicker.js +345 -0
  86. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.d.ts +11 -0
  87. package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.js +26 -0
  88. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.js +6 -6
  89. package/vscode/src/vs/sessions/contrib/search/browser/search.contribution.js +3 -3
  90. package/vscode/src/vs/sessions/contrib/search/browser/searchEditorEmptyState.contribution.js +1 -1
  91. package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.js +4 -4
  92. package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsList.js +5 -5
  93. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.js +2 -2
  94. package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.js +8 -8
  95. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.js +58 -58
  96. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.js +8 -8
  97. package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.js +5 -5
  98. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationTemplates.js +10 -10
  99. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.js +38 -38
  100. package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.js +118 -118
  101. package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.js +53 -53
  102. package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.d.ts +42 -0
  103. package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.js +139 -0
  104. package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.d.ts +120 -0
  105. package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.js +741 -0
  106. package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.js +2 -2
  107. package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.js +2 -2
  108. package/vscode/src/vs/workbench/browser/layout.js +1 -1
@@ -0,0 +1,741 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
4
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
5
+ import { isEqual } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
6
+ import { Schemas } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
7
+ import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
8
+ import { localize2 } from '@codingame/monaco-vscode-api/vscode/vs/nls';
9
+ import { Action2, registerAction2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
10
+ import { AGENT_HOST_SCHEME, fromAgentHostUri } from '@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/agentHostUri';
11
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
12
+ import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
13
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
14
+ import { registerWorkbenchContribution2, WorkbenchPhase, getWorkbenchContribution } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions';
15
+ import { IAgentHostTerminalService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/browser/agentHostTerminalService.service';
16
+ import { ITerminalService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/browser/terminal.service';
17
+ import { TerminalCapability } from '@codingame/monaco-vscode-api/vscode/vs/platform/terminal/common/capabilities/capabilities';
18
+ import { IPathService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/path/common/pathService.service';
19
+ import { LOCAL_AGENT_HOST_PROVIDER_ID, isAgentHostProvider } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/agentHostSessionsProvider';
20
+ import { ISessionsManagementService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/sessionsManagement.service';
21
+ import { ISessionsService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/browser/sessionsService.service';
22
+ import { ISessionsProvidersService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/browser/sessionsProvidersService.service';
23
+ import { ITerminalProfileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/common/terminal.service';
24
+ import { ISessionTaskRunnerRegistry } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/sessionTaskRunner.service';
25
+ import { AgentHostSessionTaskRunner } from './agentHostSessionTaskRunner.js';
26
+ import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
27
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
28
+
29
+ function getSessionTerminalInfo(session, reader) {
30
+ if (!session) {
31
+ return undefined;
32
+ }
33
+ const workspace = reader ? session.workspace.read(reader) : session.workspace.get();
34
+ if (workspace?.isVirtualWorkspace !== false) {
35
+ return undefined;
36
+ }
37
+ const folder = workspace.folders[0];
38
+ const cwd = folder?.workingDirectory;
39
+ if (!cwd) {
40
+ return undefined;
41
+ }
42
+ if (cwd.scheme === AGENT_HOST_SCHEME) {
43
+ return {
44
+ cwd: fromAgentHostUri(cwd),
45
+ agentHostCwd: cwd
46
+ };
47
+ }
48
+ return {
49
+ cwd
50
+ };
51
+ }
52
+ function getSessionWorktreeCwd(session) {
53
+ const worktree = session.workspace.get()?.folders[0]?.gitRepository?.workTreeUri;
54
+ return worktree?.scheme === AGENT_HOST_SCHEME ? undefined : worktree;
55
+ }
56
+ let SessionsTerminalContribution = class SessionsTerminalContribution extends Disposable {
57
+ static {
58
+ this.ID = "workbench.contrib.sessionsTerminal";
59
+ }
60
+ constructor(
61
+ _sessionsManagementService,
62
+ _sessionsService,
63
+ _sessionsProvidersService,
64
+ _terminalService,
65
+ _agentHostTerminalService,
66
+ _logService,
67
+ _pathService,
68
+ _fileService,
69
+ _terminalProfileService
70
+ ) {
71
+ super();
72
+ this._sessionsManagementService = _sessionsManagementService;
73
+ this._sessionsService = _sessionsService;
74
+ this._sessionsProvidersService = _sessionsProvidersService;
75
+ this._terminalService = _terminalService;
76
+ this._agentHostTerminalService = _agentHostTerminalService;
77
+ this._logService = _logService;
78
+ this._pathService = _pathService;
79
+ this._fileService = _fileService;
80
+ this._terminalProfileService = _terminalProfileService;
81
+ this._sessionTerminals = ( new Map());
82
+ this._standaloneTerminalIds = ( new Set());
83
+ this._pendingTerminalOperations = ( new Map());
84
+ this._sessionTerminalGenerations = ( new Map());
85
+ this._archivedSessionIds = ( new Set());
86
+ for (const session of this._sessionsManagementService.getSessions()) {
87
+ if (session.isArchived.get()) {
88
+ this._archivedSessionIds.add(session.sessionId);
89
+ }
90
+ }
91
+ const profileOverride = derived(reader => {
92
+ const session = this._sessionsService.activeSession.read(reader);
93
+ if (!session || session.providerId === LOCAL_AGENT_HOST_PROVIDER_ID) {
94
+ return;
95
+ }
96
+ const address = this._getSessionAgentHostAddress(session);
97
+ if (!address) {
98
+ return;
99
+ }
100
+ const profiles = this._agentHostTerminalService.profiles.read(reader);
101
+ return profiles.find(p => p.address === address) ?? this._agentHostTerminalService.getProfileForConnection(address);
102
+ });
103
+ this._register(autorun(reader => {
104
+ const profile = profileOverride.read(reader);
105
+ if (profile) {
106
+ reader.store.add(
107
+ this._terminalProfileService.overrideDefaultProfile(profile.extensionIdentifier, profile.profileId)
108
+ );
109
+ }
110
+ }));
111
+ this._register(autorun(reader => {
112
+ const session = this._sessionsService.activeSession.read(reader);
113
+ const remoteConnectionStatus = session?.remoteConnectionStatus?.read(reader);
114
+ const remoteHostAvailable = remoteConnectionStatus === undefined || remoteConnectionStatus.kind === "connected";
115
+ if (session?.loading.read(reader) || session?.isArchived.read(reader) || session?.worktreePending?.read(reader) || !remoteHostAvailable) {
116
+ this._agentHostTerminalService.setDefaultCwd(undefined);
117
+ return;
118
+ }
119
+ const info = getSessionTerminalInfo(session, reader);
120
+ this._agentHostTerminalService.setDefaultCwd(info?.cwd);
121
+ }));
122
+ this._register(autorun(reader => {
123
+ const session = this._sessionsService.activeSession.read(reader);
124
+ const isArchived = session?.isArchived.read(reader);
125
+ const worktreePending = session?.worktreePending?.read(reader);
126
+ const remoteConnectionStatus = session?.remoteConnectionStatus?.read(reader);
127
+ const remoteHostAvailable = remoteConnectionStatus === undefined || remoteConnectionStatus.kind === "connected";
128
+ const remoteHostPermanentlyUnavailable = remoteConnectionStatus?.kind === "disconnected" || remoteConnectionStatus?.kind === "incompatible";
129
+ const preserveActiveTerminalState = !remoteHostPermanentlyUnavailable && !remoteHostAvailable && this._activeSessionId === session?.sessionId;
130
+ if (session && !isArchived && this._archivedSessionIds.delete(session.sessionId)) {
131
+ this._invalidateTerminalOperations(session.sessionId);
132
+ }
133
+ if (session?.loading.read(reader) || isArchived || worktreePending || !remoteHostAvailable) {
134
+ if (session && (isArchived || worktreePending || !remoteHostAvailable)) {
135
+ this._invalidateTerminalOperations(session.sessionId);
136
+ }
137
+ if (!preserveActiveTerminalState) {
138
+ this._activeKey = undefined;
139
+ this._activeSessionId = undefined;
140
+ }
141
+ return;
142
+ }
143
+ this._onActiveSessionChanged(session);
144
+ }));
145
+ this._register(this._sessionsManagementService.onDidReplaceNewDraftSession((
146
+ {
147
+ from,
148
+ to
149
+ }
150
+ ) => {
151
+ this._onDidReplaceNewDraftSession(from, to);
152
+ }));
153
+ this._register(this._sessionsManagementService.onDidReplaceSession((
154
+ {
155
+ from,
156
+ to
157
+ }
158
+ ) => {
159
+ this._transferTerminals(from.sessionId, to.sessionId);
160
+ }));
161
+ this._register(this._terminalService.onDidDisposeInstance(instance => {
162
+ this._removeTerminalFromTrackedSessions(instance.instanceId);
163
+ this._standaloneTerminalIds.delete(instance.instanceId);
164
+ }));
165
+ this._register(this._terminalService.onDidCreateInstance(instance => {
166
+ if (instance.shellLaunchConfig.hideFromUser) {
167
+ return;
168
+ }
169
+ if (instance.shellLaunchConfig.attachPersistentProcess && this._activeKey) {
170
+ instance.getInitialCwd().then(cwd => {
171
+ if (cwd.toLowerCase() !== this._activeKey) {
172
+ const availableInstance = this._getAvailableTerminal(instance, `hide restored terminal for ${cwd}`);
173
+ if (!availableInstance) {
174
+ return;
175
+ }
176
+ this._terminalService.moveToBackground(availableInstance);
177
+ this._logService.trace(
178
+ `[SessionsTerminal] Hid restored terminal ${availableInstance.instanceId} (cwd: ${cwd})`
179
+ );
180
+ }
181
+ });
182
+ }
183
+ }));
184
+ this._register(this._sessionsManagementService.onDidChangeSessions(e => {
185
+ for (const session of e.added) {
186
+ if (session.isArchived.get()) {
187
+ this._archivedSessionIds.add(session.sessionId);
188
+ }
189
+ }
190
+ const justArchived = [];
191
+ for (const session of e.changed) {
192
+ if (session.isArchived.get()) {
193
+ if (!( this._archivedSessionIds.has(session.sessionId))) {
194
+ this._archivedSessionIds.add(session.sessionId);
195
+ this._invalidateTerminalOperations(session.sessionId);
196
+ justArchived.push(session);
197
+ }
198
+ } else {
199
+ if (this._archivedSessionIds.delete(session.sessionId)) {
200
+ this._invalidateTerminalOperations(session.sessionId);
201
+ }
202
+ }
203
+ }
204
+ for (const session of e.removed) {
205
+ this._archivedSessionIds.delete(session.sessionId);
206
+ }
207
+ if (e.removed.length === 0 && justArchived.length === 0) {
208
+ return;
209
+ }
210
+ this._logService.trace(
211
+ `[SessionsTerminal] onDidChangeSessions cleanup (removed: ${e.removed.length}, justArchived: ${justArchived.length}, trackedSessions: ${this._sessionTerminals.size}, activeKey: ${this._activeKey ?? "<none>"})`
212
+ );
213
+ for (const session of e.removed) {
214
+ void this._closeTerminalsForSession(session.sessionId, `session removed (${session.sessionId})`).finally(() => this._sessionTerminals.delete(session.sessionId));
215
+ }
216
+ for (const session of justArchived) {
217
+ void this._closeArchivedSessionTerminals(session);
218
+ }
219
+ }));
220
+ }
221
+ async ensureTerminal(cwd, focus, session) {
222
+ if (!session) {
223
+ return this._ensureTerminal(cwd, focus, session);
224
+ }
225
+ if (!this._isSessionRemoteHostAvailable(session)) {
226
+ return [];
227
+ }
228
+ const generation = this._getTerminalOperationGeneration(session.sessionId);
229
+ this._beginTerminalOperation(session.sessionId);
230
+ try {
231
+ return await this._ensureTerminal(cwd, focus, session, generation);
232
+ } finally {
233
+ this._endTerminalOperation(session.sessionId);
234
+ }
235
+ }
236
+ async _ensureTerminal(cwd, focus, session, generation) {
237
+ if (session && this._isTerminalOperationCancelled(session, generation)) {
238
+ return [];
239
+ }
240
+ const key = cwd.fsPath.toLowerCase();
241
+ let existing = session ? this._getTrackedTerminalsForSession(session.sessionId) : [];
242
+ if (existing.length === 0) {
243
+ existing = await this._findTerminalsForKey(key, {
244
+ excludeTracked: !!session
245
+ });
246
+ if (session && this._isTerminalOperationCancelled(session, generation)) {
247
+ return [];
248
+ }
249
+ }
250
+ if (existing.length === 0) {
251
+ try {
252
+ const instance = await this._createTerminalForSession(cwd, session);
253
+ const createdInstance = this._getAvailableTerminal(instance, `activate created terminal for ${cwd.fsPath}`);
254
+ if (!createdInstance) {
255
+ return [];
256
+ }
257
+ if (session && this._isTerminalOperationCancelled(session, generation)) {
258
+ await this._terminalService.safeDisposeTerminal(createdInstance);
259
+ if (!createdInstance.isDisposed) {
260
+ this._trackTerminalsForSession(session.sessionId, [createdInstance]);
261
+ }
262
+ return [];
263
+ }
264
+ existing = [createdInstance];
265
+ this._terminalService.setActiveInstance(createdInstance);
266
+ this._logService.trace(
267
+ `[SessionsTerminal] Created terminal ${createdInstance.instanceId} for ${cwd.fsPath}`
268
+ );
269
+ } catch (e) {
270
+ this._logService.trace(`[SessionsTerminal] Cannot create terminal for ${cwd.fsPath}: ${e}`);
271
+ return [];
272
+ }
273
+ }
274
+ if (session) {
275
+ this._trackTerminalsForSession(session.sessionId, existing);
276
+ }
277
+ if (focus) {
278
+ await this._terminalService.focusActiveInstance();
279
+ }
280
+ return existing;
281
+ }
282
+ _isTerminalOperationCancelled(
283
+ session,
284
+ generation = this._getTerminalOperationGeneration(session.sessionId)
285
+ ) {
286
+ return this._pendingTerminalOperations.get(session.sessionId)?.replaced === true || this._getTerminalOperationGeneration(session.sessionId) !== generation || ( this._archivedSessionIds.has(session.sessionId)) || session.isArchived.get() || session.worktreePending?.get() === true || !this._isSessionRemoteHostAvailable(session);
287
+ }
288
+ _isSessionRemoteHostAvailable(session) {
289
+ const status = session.remoteConnectionStatus?.get();
290
+ return status === undefined || status.kind === "connected";
291
+ }
292
+ _getTerminalOperationGeneration(sessionId) {
293
+ return this._sessionTerminalGenerations.get(sessionId) ?? 0;
294
+ }
295
+ _invalidateTerminalOperations(sessionId) {
296
+ this._sessionTerminalGenerations.set(sessionId, this._getTerminalOperationGeneration(sessionId) + 1);
297
+ }
298
+ async _createTerminalForSession(cwd, session) {
299
+ const address = session && this._getSessionAgentHostAddress(session);
300
+ if (address) {
301
+ const instance = await this._agentHostTerminalService.createTerminalForEntry(address, {
302
+ cwd
303
+ });
304
+ if (instance) {
305
+ return instance;
306
+ }
307
+ }
308
+ return this._terminalService.createTerminal({
309
+ config: {
310
+ cwd
311
+ }
312
+ });
313
+ }
314
+ _getSessionAgentHostAddress(session) {
315
+ if (!session) {
316
+ return undefined;
317
+ }
318
+ const provider = this._sessionsProvidersService.getProvider(session.providerId);
319
+ if (!provider || !isAgentHostProvider(provider)) {
320
+ return undefined;
321
+ }
322
+ return provider.remoteAddress ?? "__local__";
323
+ }
324
+ async _onActiveSessionChanged(session) {
325
+ if (!session) {
326
+ return;
327
+ }
328
+ this._beginTerminalOperation(session.sessionId);
329
+ try {
330
+ const generation = this._getTerminalOperationGeneration(session.sessionId);
331
+ const info = getSessionTerminalInfo(session);
332
+ if (info?.cwd && !info.agentHostCwd && info.cwd.scheme === Schemas.file && !(await this._fileService.exists(info.cwd))) {
333
+ return;
334
+ }
335
+ const targetPath = info?.cwd ?? (await this._pathService.userHome());
336
+ const targetKey = targetPath.fsPath.toLowerCase();
337
+ if (this._activeKey === targetKey && this._activeSessionId === session.sessionId) {
338
+ return;
339
+ }
340
+ this._activeKey = targetKey;
341
+ this._activeSessionId = session.sessionId;
342
+ const instances = await this._ensureTerminal(targetPath, false, session, generation);
343
+ if (this._activeKey !== targetKey || this._activeSessionId !== session.sessionId) {
344
+ return;
345
+ }
346
+ await this._updateTerminalVisibility(session, targetKey, instances.map(instance => instance.instanceId));
347
+ } finally {
348
+ this._endTerminalOperation(session.sessionId);
349
+ }
350
+ }
351
+ async _findTerminalsForKey(key, options) {
352
+ const result = [];
353
+ for (const instance of this._terminalService.instances) {
354
+ if (instance.shellLaunchConfig.hideFromUser) {
355
+ continue;
356
+ }
357
+ if (options?.excludeTracked && (this._isTerminalTracked(instance.instanceId) || ( this._standaloneTerminalIds.has(instance.instanceId)))) {
358
+ continue;
359
+ }
360
+ try {
361
+ const cwd = await instance.getInitialCwd();
362
+ if (cwd.toLowerCase() === key) {
363
+ result.push(instance);
364
+ }
365
+ } catch {}
366
+ }
367
+ return result;
368
+ }
369
+ _trackTerminalsForSession(sessionId, instances) {
370
+ if (instances.length === 0) {
371
+ return;
372
+ }
373
+ let terminalIds = this._sessionTerminals.get(sessionId);
374
+ if (!terminalIds) {
375
+ terminalIds = ( new Set());
376
+ this._sessionTerminals.set(sessionId, terminalIds);
377
+ }
378
+ for (const instance of instances) {
379
+ terminalIds.add(instance.instanceId);
380
+ }
381
+ }
382
+ _beginTerminalOperation(sessionId) {
383
+ const operation = this._pendingTerminalOperations.get(sessionId);
384
+ if (operation) {
385
+ operation.count++;
386
+ return;
387
+ }
388
+ this._pendingTerminalOperations.set(sessionId, {
389
+ count: 1,
390
+ replaced: false
391
+ });
392
+ }
393
+ _endTerminalOperation(sessionId) {
394
+ const operation = this._pendingTerminalOperations.get(sessionId);
395
+ if (!operation) {
396
+ return;
397
+ }
398
+ operation.count--;
399
+ if (operation.count > 0) {
400
+ return;
401
+ }
402
+ this._pendingTerminalOperations.delete(sessionId);
403
+ }
404
+ _onDidReplaceNewDraftSession(from, to) {
405
+ const pendingOperation = this._pendingTerminalOperations.get(from.sessionId);
406
+ if (pendingOperation) {
407
+ pendingOperation.replaced = true;
408
+ }
409
+ const fromCwd = getSessionTerminalInfo(from)?.cwd.fsPath.toLowerCase();
410
+ const toCwd = getSessionTerminalInfo(to)?.cwd.fsPath.toLowerCase();
411
+ const fromAgentHostAddress = this._getSessionAgentHostAddress(from);
412
+ const toAgentHostAddress = this._getSessionAgentHostAddress(to);
413
+ if (fromCwd === toCwd && fromAgentHostAddress === toAgentHostAddress) {
414
+ this._transferTerminals(from.sessionId, to.sessionId);
415
+ } else {
416
+ this._rehomeTerminals(from.sessionId);
417
+ }
418
+ }
419
+ _rehomeTerminals(sessionId) {
420
+ const terminals = this._getTrackedTerminalsForSession(sessionId);
421
+ for (const terminal of terminals) {
422
+ this._standaloneTerminalIds.add(terminal.instanceId);
423
+ }
424
+ if (terminals.length > 0) {
425
+ this._logService.trace(
426
+ `[SessionsTerminal] Rehomed ${terminals.length} terminal(s) from session ${sessionId}`
427
+ );
428
+ }
429
+ this._sessionTerminals.delete(sessionId);
430
+ }
431
+ _transferTerminals(fromSessionId, toSessionId) {
432
+ const terminalIds = this._sessionTerminals.get(fromSessionId);
433
+ if (terminalIds && terminalIds.size > 0) {
434
+ let targetIds = this._sessionTerminals.get(toSessionId);
435
+ if (!targetIds) {
436
+ targetIds = ( new Set());
437
+ this._sessionTerminals.set(toSessionId, targetIds);
438
+ }
439
+ for (const id of terminalIds) {
440
+ targetIds.add(id);
441
+ }
442
+ this._logService.trace(
443
+ `[SessionsTerminal] Transferred ${terminalIds.size} terminal(s) from session ${fromSessionId} to ${toSessionId}`
444
+ );
445
+ }
446
+ this._sessionTerminals.delete(fromSessionId);
447
+ }
448
+ _getTrackedTerminalsForSession(sessionId) {
449
+ const terminalIds = this._sessionTerminals.get(sessionId);
450
+ if (!terminalIds) {
451
+ return [];
452
+ }
453
+ const result = [];
454
+ for (const instanceId of [...terminalIds]) {
455
+ const instance = this._terminalService.getInstanceFromId(instanceId);
456
+ if (!instance || instance.isDisposed || instance.shellLaunchConfig.hideFromUser) {
457
+ terminalIds.delete(instanceId);
458
+ continue;
459
+ }
460
+ result.push(instance);
461
+ }
462
+ if (terminalIds.size === 0) {
463
+ this._sessionTerminals.delete(sessionId);
464
+ }
465
+ return result;
466
+ }
467
+ _isTerminalTracked(instanceId) {
468
+ for (const [sessionId, terminalIds] of this._sessionTerminals) {
469
+ if (( terminalIds.has(instanceId))) {
470
+ const instance = this._terminalService.getInstanceFromId(instanceId);
471
+ if (!instance || instance.isDisposed) {
472
+ terminalIds.delete(instanceId);
473
+ if (terminalIds.size === 0) {
474
+ this._sessionTerminals.delete(sessionId);
475
+ }
476
+ continue;
477
+ }
478
+ return true;
479
+ }
480
+ }
481
+ return false;
482
+ }
483
+ _removeTerminalFromTrackedSessions(instanceId) {
484
+ for (const [sessionId, terminalIds] of this._sessionTerminals) {
485
+ terminalIds.delete(instanceId);
486
+ if (terminalIds.size === 0) {
487
+ this._sessionTerminals.delete(sessionId);
488
+ }
489
+ }
490
+ }
491
+ _getAvailableTerminal(instance, action) {
492
+ const currentInstance = this._terminalService.getInstanceFromId(instance.instanceId);
493
+ if (!currentInstance || currentInstance.isDisposed) {
494
+ this._logService.trace(
495
+ `[SessionsTerminal] Cannot ${action}; terminal ${instance.instanceId} is no longer available`
496
+ );
497
+ return undefined;
498
+ }
499
+ return currentInstance;
500
+ }
501
+ async _updateTerminalVisibility(activeSession, activeKey, forceForegroundTerminalIds) {
502
+ const toShow = [];
503
+ const toHide = [];
504
+ const trackedTerminalIds = ( new Set(
505
+ this._getTrackedTerminalsForSession(activeSession.sessionId).map(instance => instance.instanceId)
506
+ ));
507
+ for (const instance of [...this._terminalService.instances]) {
508
+ if (instance.shellLaunchConfig.hideFromUser || ( this._standaloneTerminalIds.has(instance.instanceId))) {
509
+ continue;
510
+ }
511
+ let cwd;
512
+ const currentInstance = this._getAvailableTerminal(instance, "update terminal visibility");
513
+ if (!currentInstance) {
514
+ continue;
515
+ }
516
+ const isForeground = this._terminalService.foregroundInstances.includes(currentInstance);
517
+ const isForceVisible = forceForegroundTerminalIds.includes(currentInstance.instanceId);
518
+ let belongsToActiveSession = ( trackedTerminalIds.has(currentInstance.instanceId));
519
+ if (!belongsToActiveSession && !this._isTerminalTracked(currentInstance.instanceId)) {
520
+ try {
521
+ cwd = (await currentInstance.getInitialCwd()).toLowerCase();
522
+ } catch {
523
+ continue;
524
+ }
525
+ belongsToActiveSession = cwd === activeKey;
526
+ }
527
+ if ((belongsToActiveSession || isForceVisible) && !isForeground) {
528
+ toShow.push(currentInstance);
529
+ } else if (!belongsToActiveSession && !isForceVisible && isForeground) {
530
+ toHide.push(currentInstance);
531
+ }
532
+ }
533
+ for (const instance of toShow) {
534
+ const availableInstance = this._getAvailableTerminal(instance, "show background terminal");
535
+ if (availableInstance) {
536
+ await this._terminalService.showBackgroundTerminal(availableInstance, true);
537
+ }
538
+ }
539
+ for (const instance of toHide) {
540
+ const availableInstance = this._getAvailableTerminal(instance, "move terminal to background");
541
+ if (availableInstance) {
542
+ this._logService.debug(
543
+ `[SessionsTerminal] Hiding terminal ${availableInstance.instanceId} (does not belong to active key ${activeKey})`
544
+ );
545
+ this._terminalService.moveToBackground(availableInstance);
546
+ }
547
+ }
548
+ const foreground = this._terminalService.foregroundInstances;
549
+ let mostRecent;
550
+ let mostRecentTimestamp = -1;
551
+ for (const instance of foreground) {
552
+ if (( this._standaloneTerminalIds.has(instance.instanceId))) {
553
+ continue;
554
+ }
555
+ const cmdDetection = instance.capabilities.get(TerminalCapability.CommandDetection);
556
+ const lastCmd = cmdDetection?.commands.at(-1);
557
+ if (lastCmd && lastCmd.timestamp > mostRecentTimestamp) {
558
+ mostRecentTimestamp = lastCmd.timestamp;
559
+ mostRecent = instance;
560
+ }
561
+ }
562
+ if (mostRecent) {
563
+ this._terminalService.setActiveInstance(mostRecent);
564
+ }
565
+ }
566
+ async _closeTerminalsForSession(sessionId, reason) {
567
+ const protectedInstanceId = this._terminalService.activeInstance?.instanceId;
568
+ for (const instance of this._getTrackedTerminalsForSession(sessionId)) {
569
+ if (protectedInstanceId !== undefined && instance.instanceId === protectedInstanceId) {
570
+ this._logService.info(
571
+ `[SessionsTerminal] Skipping active terminal ${instance.instanceId} for session ${sessionId} (user is working in it)`
572
+ );
573
+ continue;
574
+ }
575
+ const availableInstance = this._getAvailableTerminal(instance, `close removed session terminal for session ${sessionId}`);
576
+ if (!availableInstance) {
577
+ continue;
578
+ }
579
+ this._logService.info(
580
+ `[SessionsTerminal] Killing terminal ${availableInstance.instanceId} (session: ${sessionId}, reason: ${reason})`
581
+ );
582
+ await this._terminalService.safeDisposeTerminal(availableInstance);
583
+ this._removeTerminalFromTrackedSessions(availableInstance.instanceId);
584
+ }
585
+ }
586
+ async _closeArchivedSessionTerminals(session) {
587
+ const cleanupGeneration = this._getTerminalOperationGeneration(session.sessionId);
588
+ const terminals = ( new Map(
589
+ this._getTrackedTerminalsForSession(session.sessionId).map(instance => [instance.instanceId, instance])
590
+ ));
591
+ const untrackedWorktreeTerminalIds = ( new Set());
592
+ const worktreeCwd = getSessionWorktreeCwd(session);
593
+ const anotherLiveSessionSharesWorktree = worktreeCwd && ( this._sessionsManagementService.getSessions().some(
594
+ candidate => candidate.sessionId !== session.sessionId && !candidate.isArchived.get() && isEqual(getSessionWorktreeCwd(candidate), worktreeCwd)
595
+ ));
596
+ if (worktreeCwd && !anotherLiveSessionSharesWorktree) {
597
+ for (const instance of await this._findUntrackedTerminalsForResource(worktreeCwd)) {
598
+ if (instance.instanceId === this._terminalService.activeInstance?.instanceId) {
599
+ continue;
600
+ }
601
+ terminals.set(instance.instanceId, instance);
602
+ untrackedWorktreeTerminalIds.add(instance.instanceId);
603
+ }
604
+ }
605
+ if (!this._isArchiveCleanupCurrent(session.sessionId, cleanupGeneration)) {
606
+ return;
607
+ }
608
+ for (const instance of ( terminals.values())) {
609
+ if (!this._isArchiveCleanupCurrent(session.sessionId, cleanupGeneration)) {
610
+ return;
611
+ }
612
+ if (( untrackedWorktreeTerminalIds.has(instance.instanceId)) && (this._isTerminalTracked(instance.instanceId) || ( this._standaloneTerminalIds.has(instance.instanceId)) || this._terminalService.activeInstance?.instanceId === instance.instanceId)) {
613
+ continue;
614
+ }
615
+ const availableInstance = this._getAvailableTerminal(
616
+ instance,
617
+ `close archived session terminal for session ${session.sessionId}`
618
+ );
619
+ if (!availableInstance) {
620
+ continue;
621
+ }
622
+ this._logService.info(
623
+ `[SessionsTerminal] Killing terminal ${availableInstance.instanceId} (session archived: ${session.sessionId})`
624
+ );
625
+ await this._terminalService.safeDisposeTerminal(availableInstance);
626
+ if (availableInstance.isDisposed) {
627
+ this._removeTerminalFromTrackedSessions(availableInstance.instanceId);
628
+ }
629
+ if (!this._isArchiveCleanupCurrent(session.sessionId, cleanupGeneration)) {
630
+ await this._ensureActiveSessionTerminalAfterLateArchiveCleanup(session.sessionId);
631
+ return;
632
+ }
633
+ }
634
+ }
635
+ _isArchiveCleanupCurrent(sessionId, generation) {
636
+ return ( this._archivedSessionIds.has(sessionId)) && this._getTerminalOperationGeneration(sessionId) === generation;
637
+ }
638
+ async _ensureActiveSessionTerminalAfterLateArchiveCleanup(sessionId) {
639
+ const activeSession = this._sessionsService.activeSession.get();
640
+ if (!activeSession || activeSession.sessionId !== sessionId || activeSession.isArchived.get() || activeSession.loading.get() || activeSession.worktreePending?.get()) {
641
+ return;
642
+ }
643
+ this._activeKey = undefined;
644
+ this._activeSessionId = undefined;
645
+ await this._onActiveSessionChanged(activeSession);
646
+ }
647
+ async _findUntrackedTerminalsForResource(resource) {
648
+ const result = [];
649
+ for (const instance of this._terminalService.instances) {
650
+ if (!instance.shellLaunchConfig.attachPersistentProcess || instance.shellLaunchConfig.hideFromUser || this._isTerminalTracked(instance.instanceId) || ( this._standaloneTerminalIds.has(instance.instanceId))) {
651
+ continue;
652
+ }
653
+ try {
654
+ if (isEqual(URI.file(await instance.getInitialCwd()), resource) && !this._isTerminalTracked(instance.instanceId) && !( this._standaloneTerminalIds.has(instance.instanceId))) {
655
+ result.push(instance);
656
+ }
657
+ } catch {}
658
+ }
659
+ return result;
660
+ }
661
+ async dumpTracking() {
662
+ console.log(`[SessionsTerminal] Active key: ${this._activeKey ?? "<none>"}`);
663
+ console.log(`[SessionsTerminal] Session terminals: ${JSON.stringify(
664
+ [...this._sessionTerminals.entries()].map(([sessionId, terminalIds]) => [sessionId, [...terminalIds]])
665
+ )}`);
666
+ console.log(
667
+ `[SessionsTerminal] Standalone terminals: ${JSON.stringify([...this._standaloneTerminalIds])}`
668
+ );
669
+ console.log("[SessionsTerminal] === All Terminals ===");
670
+ for (const instance of this._terminalService.instances) {
671
+ let cwd = "<unknown>";
672
+ try {
673
+ cwd = await instance.getInitialCwd();
674
+ } catch {}
675
+ const isForeground = this._terminalService.foregroundInstances.includes(instance);
676
+ console.log(
677
+ ` ${instance.instanceId} - ${cwd} - ${isForeground ? "foreground" : "background"}`
678
+ );
679
+ }
680
+ }
681
+ async showAllTerminals() {
682
+ for (const instance of this._terminalService.instances) {
683
+ if (!this._terminalService.foregroundInstances.includes(instance)) {
684
+ await this._terminalService.showBackgroundTerminal(instance, true);
685
+ this._logService.trace(`[SessionsTerminal] Moved terminal ${instance.instanceId} to foreground`);
686
+ }
687
+ }
688
+ }
689
+ };
690
+ SessionsTerminalContribution = ( __decorate([( __param(0, ISessionsManagementService)), ( __param(1, ISessionsService)), ( __param(2, ISessionsProvidersService)), ( __param(3, ITerminalService)), ( __param(4, IAgentHostTerminalService)), ( __param(5, ILogService)), ( __param(6, IPathService)), ( __param(7, IFileService)), ( __param(8, ITerminalProfileService))], SessionsTerminalContribution));
691
+ registerWorkbenchContribution2(
692
+ SessionsTerminalContribution.ID,
693
+ SessionsTerminalContribution,
694
+ WorkbenchPhase.AfterRestored
695
+ );
696
+ let RegisterAgentHostSessionTaskRunnerContribution = class RegisterAgentHostSessionTaskRunnerContribution extends Disposable {
697
+ static {
698
+ this.ID = "workbench.contrib.sessions.registerAgentHostTaskRunner";
699
+ }
700
+ constructor(instantiationService, registry) {
701
+ super();
702
+ const runner = instantiationService.createInstance(AgentHostSessionTaskRunner);
703
+ this._register(registry.register(runner));
704
+ }
705
+ };
706
+ RegisterAgentHostSessionTaskRunnerContribution = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, ISessionTaskRunnerRegistry))], RegisterAgentHostSessionTaskRunnerContribution));
707
+ registerWorkbenchContribution2(
708
+ RegisterAgentHostSessionTaskRunnerContribution.ID,
709
+ RegisterAgentHostSessionTaskRunnerContribution,
710
+ WorkbenchPhase.BlockStartup
711
+ );
712
+ class DumpTerminalTrackingAction extends Action2 {
713
+ constructor() {
714
+ super({
715
+ id: "agentSession.dumpTerminalTracking",
716
+ title: ( localize2(5020, "Dump Terminal Tracking")),
717
+ f1: true
718
+ });
719
+ }
720
+ async run() {
721
+ const contribution = getWorkbenchContribution(SessionsTerminalContribution.ID);
722
+ await contribution.dumpTracking();
723
+ }
724
+ }
725
+ registerAction2(DumpTerminalTrackingAction);
726
+ class ShowAllTerminalsAction extends Action2 {
727
+ constructor() {
728
+ super({
729
+ id: "agentSession.showAllTerminals",
730
+ title: ( localize2(5021, "Show All Terminals")),
731
+ f1: true
732
+ });
733
+ }
734
+ async run() {
735
+ const contribution = getWorkbenchContribution(SessionsTerminalContribution.ID);
736
+ await contribution.showAllTerminals();
737
+ }
738
+ }
739
+ registerAction2(ShowAllTerminalsAction);
740
+
741
+ export { SessionsTerminalContribution };