@tutti-os/workspace-terminal 0.0.1
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.
- package/LICENSE +202 -0
- package/README.md +57 -0
- package/dist/chunk-56B5GYMU.js +607 -0
- package/dist/chunk-56B5GYMU.js.map +1 -0
- package/dist/chunk-65BWWZQV.js +109 -0
- package/dist/chunk-65BWWZQV.js.map +1 -0
- package/dist/chunk-FEJT6FJ4.js +1722 -0
- package/dist/chunk-FEJT6FJ4.js.map +1 -0
- package/dist/contracts/index.d.ts +167 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/feature-sh6KDO7B.d.ts +32 -0
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/index.js +13 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.d.ts +39 -0
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -0
- package/dist/styles/terminal.css +303 -0
- package/dist/workbench/index.d.ts +59 -0
- package/dist/workbench/index.js +317 -0
- package/dist/workbench/index.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
@import "@xterm/xterm/css/xterm.css";
|
|
2
|
+
|
|
3
|
+
.workbench-window-shell[data-workbench-node-type-id="workspace-terminal"]
|
|
4
|
+
.workbench-window {
|
|
5
|
+
box-shadow:
|
|
6
|
+
var(--workbench-window-shadow),
|
|
7
|
+
0 8px 24px var(--shadow-elevated);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.workspace-terminal {
|
|
11
|
+
position: relative;
|
|
12
|
+
display: flex;
|
|
13
|
+
min-height: 0;
|
|
14
|
+
height: 100%;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
background: var(--nextop-surface, #111);
|
|
17
|
+
color: var(--nextop-text, #f4f4f5);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.workspace-terminal__header {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex: none;
|
|
23
|
+
height: var(--workbench-header-height);
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: space-between;
|
|
26
|
+
gap: 12px;
|
|
27
|
+
border-bottom: 1px solid var(--border-1);
|
|
28
|
+
background: var(--background-panel);
|
|
29
|
+
color: var(--text-primary);
|
|
30
|
+
padding: 0 8px 0 12px;
|
|
31
|
+
font-size: 13px;
|
|
32
|
+
user-select: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.workspace-terminal__header-main {
|
|
36
|
+
display: flex;
|
|
37
|
+
min-width: 0;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: 8px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.workspace-terminal__title {
|
|
43
|
+
min-width: 0;
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
line-height: 1.35;
|
|
47
|
+
text-overflow: ellipsis;
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.workspace-terminal__status-tag {
|
|
52
|
+
flex: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.workspace-terminal__actions {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex: none;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 4px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.workspace-terminal__icon-button {
|
|
63
|
+
display: grid;
|
|
64
|
+
width: 28px;
|
|
65
|
+
height: 28px;
|
|
66
|
+
place-items: center;
|
|
67
|
+
border: 0;
|
|
68
|
+
border-radius: 6px;
|
|
69
|
+
background: transparent;
|
|
70
|
+
color: inherit;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.workspace-terminal__body {
|
|
74
|
+
min-height: 0;
|
|
75
|
+
flex: 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.workspace-terminal__surface-shell {
|
|
79
|
+
position: relative;
|
|
80
|
+
min-height: 0;
|
|
81
|
+
height: 100%;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.workspace-terminal__find {
|
|
85
|
+
position: absolute;
|
|
86
|
+
top: 10px;
|
|
87
|
+
right: 10px;
|
|
88
|
+
z-index: 2;
|
|
89
|
+
display: grid;
|
|
90
|
+
grid-template-columns: minmax(150px, 210px) 30px 30px 34px 34px;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: 5px;
|
|
93
|
+
max-width: min(352px, calc(100% - 20px));
|
|
94
|
+
border: 1px solid rgb(255 255 255 / 10%);
|
|
95
|
+
border-radius: 999px;
|
|
96
|
+
background: linear-gradient(180deg, rgb(39 39 42 / 94%), rgb(15 23 42 / 92%));
|
|
97
|
+
box-shadow:
|
|
98
|
+
0 12px 28px rgb(0 0 0 / 30%),
|
|
99
|
+
inset 0 1px 0 rgb(255 255 255 / 7%);
|
|
100
|
+
padding: 5px;
|
|
101
|
+
backdrop-filter: blur(10px);
|
|
102
|
+
animation: workspace-terminal__find-enter 140ms ease-out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.workspace-terminal__find input {
|
|
106
|
+
min-width: 0;
|
|
107
|
+
height: 28px;
|
|
108
|
+
border: 1px solid transparent;
|
|
109
|
+
border-radius: 999px;
|
|
110
|
+
background: rgb(5 8 18 / 78%);
|
|
111
|
+
color: rgb(244 244 245);
|
|
112
|
+
font-size: 12px;
|
|
113
|
+
line-height: 1;
|
|
114
|
+
outline: none;
|
|
115
|
+
padding: 0 11px;
|
|
116
|
+
box-shadow: inset 0 1px 2px rgb(0 0 0 / 24%);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.workspace-terminal__find input:focus {
|
|
120
|
+
border-color: rgb(125 211 252 / 44%);
|
|
121
|
+
box-shadow:
|
|
122
|
+
inset 0 1px 2px rgb(0 0 0 / 24%),
|
|
123
|
+
0 0 0 1px rgb(125 211 252 / 22%);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.workspace-terminal__find button {
|
|
127
|
+
display: grid;
|
|
128
|
+
min-width: 30px;
|
|
129
|
+
height: 28px;
|
|
130
|
+
place-items: center;
|
|
131
|
+
border: 1px solid transparent;
|
|
132
|
+
border-radius: 999px;
|
|
133
|
+
background: rgb(255 255 255 / 2%);
|
|
134
|
+
color: rgb(244 244 245 / 82%);
|
|
135
|
+
font-size: 11px;
|
|
136
|
+
line-height: 1;
|
|
137
|
+
padding: 0 8px;
|
|
138
|
+
transition:
|
|
139
|
+
background-color 120ms ease,
|
|
140
|
+
border-color 120ms ease,
|
|
141
|
+
color 120ms ease,
|
|
142
|
+
transform 120ms ease;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.workspace-terminal__find button:hover {
|
|
146
|
+
background: rgb(255 255 255 / 7%);
|
|
147
|
+
color: rgb(244 244 245);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.workspace-terminal__find button:active {
|
|
151
|
+
transform: translateY(1px);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.workspace-terminal__find button[aria-pressed="true"] {
|
|
155
|
+
border-color: rgb(125 211 252 / 18%);
|
|
156
|
+
background: rgb(14 116 144 / 24%);
|
|
157
|
+
color: rgb(224 242 254);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.workspace-terminal__find button:focus-visible {
|
|
161
|
+
border-color: rgb(125 211 252 / 42%);
|
|
162
|
+
outline: none;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.workspace-terminal__find-toggle {
|
|
166
|
+
font-weight: 600;
|
|
167
|
+
letter-spacing: 0.02em;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.workspace-terminal__find-nav {
|
|
171
|
+
position: relative;
|
|
172
|
+
min-width: 30px;
|
|
173
|
+
padding: 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.workspace-terminal__find-nav::before {
|
|
177
|
+
content: "";
|
|
178
|
+
width: 7px;
|
|
179
|
+
height: 7px;
|
|
180
|
+
border-top: 1.5px solid currentColor;
|
|
181
|
+
border-right: 1.5px solid currentColor;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.workspace-terminal__find-nav--previous::before {
|
|
185
|
+
transform: rotate(-135deg);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.workspace-terminal__find-nav--next::before {
|
|
189
|
+
transform: rotate(45deg);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes workspace-terminal__find-enter {
|
|
193
|
+
from {
|
|
194
|
+
opacity: 0;
|
|
195
|
+
transform: translateY(-4px) scale(0.985);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
to {
|
|
199
|
+
opacity: 1;
|
|
200
|
+
transform: translateY(0) scale(1);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.workspace-terminal__xterm {
|
|
205
|
+
height: 100%;
|
|
206
|
+
min-height: 0;
|
|
207
|
+
overflow: hidden;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.workspace-terminal__xterm .xterm {
|
|
211
|
+
height: 100%;
|
|
212
|
+
padding: 8px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.workspace-terminal__surface-error {
|
|
216
|
+
position: absolute;
|
|
217
|
+
right: 8px;
|
|
218
|
+
bottom: 8px;
|
|
219
|
+
max-width: min(420px, calc(100% - 16px));
|
|
220
|
+
border: 1px solid rgb(248 113 113 / 50%);
|
|
221
|
+
border-radius: 6px;
|
|
222
|
+
background: rgb(69 10 10 / 92%);
|
|
223
|
+
color: rgb(254 226 226);
|
|
224
|
+
font-size: 12px;
|
|
225
|
+
line-height: 1.4;
|
|
226
|
+
padding: 6px 8px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.workspace-terminal__placeholder {
|
|
230
|
+
display: grid;
|
|
231
|
+
height: 100%;
|
|
232
|
+
min-height: 160px;
|
|
233
|
+
place-items: center;
|
|
234
|
+
color: var(--nextop-text-muted, rgb(244 244 245 / 68%));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.workspace-terminal__close-guard {
|
|
238
|
+
position: absolute;
|
|
239
|
+
inset: 0;
|
|
240
|
+
z-index: 4;
|
|
241
|
+
display: grid;
|
|
242
|
+
place-content: center;
|
|
243
|
+
gap: 12px;
|
|
244
|
+
background: rgb(0 0 0 / 42%);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.workspace-terminal__close-guard > h2,
|
|
248
|
+
.workspace-terminal__close-guard > p,
|
|
249
|
+
.workspace-terminal__close-guard > code,
|
|
250
|
+
.workspace-terminal__close-guard-actions {
|
|
251
|
+
width: min(360px, calc(100vw - 48px));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.workspace-terminal__close-guard > h2 {
|
|
255
|
+
margin: 0;
|
|
256
|
+
font-size: 16px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.workspace-terminal__close-guard > p {
|
|
260
|
+
margin: 0;
|
|
261
|
+
color: var(--nextop-text-muted, rgb(244 244 245 / 68%));
|
|
262
|
+
font-size: 13px;
|
|
263
|
+
line-height: 1.5;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.workspace-terminal__close-guard > code {
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
border-radius: 4px;
|
|
269
|
+
background: rgb(0 0 0 / 32%);
|
|
270
|
+
color: inherit;
|
|
271
|
+
font-size: 12px;
|
|
272
|
+
padding: 6px 8px;
|
|
273
|
+
text-overflow: ellipsis;
|
|
274
|
+
white-space: nowrap;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.workspace-terminal__close-guard-actions {
|
|
278
|
+
display: flex;
|
|
279
|
+
justify-content: flex-end;
|
|
280
|
+
gap: 8px;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.workspace-terminal__close-error {
|
|
284
|
+
position: absolute;
|
|
285
|
+
right: 8px;
|
|
286
|
+
bottom: 8px;
|
|
287
|
+
z-index: 5;
|
|
288
|
+
max-width: min(420px, calc(100% - 16px));
|
|
289
|
+
border: 1px solid rgb(248 113 113 / 50%);
|
|
290
|
+
border-radius: 6px;
|
|
291
|
+
background: rgb(69 10 10 / 92%);
|
|
292
|
+
color: rgb(254 226 226);
|
|
293
|
+
font-size: 12px;
|
|
294
|
+
line-height: 1.4;
|
|
295
|
+
padding: 6px 8px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.workspace-terminal__dock-icon {
|
|
299
|
+
font-family:
|
|
300
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
301
|
+
"Courier New", monospace;
|
|
302
|
+
font-weight: 700;
|
|
303
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { WorkbenchHostExternalStateSource, WorkbenchFrame, WorkbenchHostLaunchRequest, WorkbenchHostDockEntry, WorkbenchContribution, WorkbenchHostLaunchResult, WorkbenchHostNodeDefinition } from '@tutti-os/workbench-surface';
|
|
3
|
+
import { TerminalNodeExternalState, TerminalHeaderAccessoryRenderer, TerminalCloseGuardResult, TerminalLaunchInput } from '../contracts/index.js';
|
|
4
|
+
import { T as TerminalNodeFeature } from '../feature-sh6KDO7B.js';
|
|
5
|
+
import '@tutti-os/ui-i18n-runtime';
|
|
6
|
+
import '../i18n/index.js';
|
|
7
|
+
|
|
8
|
+
interface TerminalWorkbenchIntent {
|
|
9
|
+
cwd?: string | null;
|
|
10
|
+
initialInput?: string | null;
|
|
11
|
+
profileId?: string | null;
|
|
12
|
+
}
|
|
13
|
+
interface CreateTerminalWorkbenchNodeDefinitionInput {
|
|
14
|
+
feature: TerminalNodeFeature;
|
|
15
|
+
frame?: WorkbenchFrame;
|
|
16
|
+
headerAccessory?: TerminalHeaderAccessoryRenderer;
|
|
17
|
+
title?: string;
|
|
18
|
+
typeId?: string;
|
|
19
|
+
}
|
|
20
|
+
type TerminalWorkbenchLaunchInputResolver = (request: WorkbenchHostLaunchRequest) => Promise<Partial<Omit<TerminalLaunchInput, "reason" | "workspaceId">>> | Partial<Omit<TerminalLaunchInput, "reason" | "workspaceId">>;
|
|
21
|
+
interface CreateTerminalWorkbenchLaunchHandlerInput {
|
|
22
|
+
feature: TerminalNodeFeature;
|
|
23
|
+
frame?: WorkbenchFrame;
|
|
24
|
+
resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;
|
|
25
|
+
typeId?: string;
|
|
26
|
+
}
|
|
27
|
+
interface CreateTerminalDockEntryInput {
|
|
28
|
+
dockIcon?: ReactNode;
|
|
29
|
+
feature: TerminalNodeFeature;
|
|
30
|
+
id?: string;
|
|
31
|
+
order?: number;
|
|
32
|
+
sectionId?: string;
|
|
33
|
+
typeId?: string;
|
|
34
|
+
}
|
|
35
|
+
interface TerminalWorkbenchContributionCloseFailure {
|
|
36
|
+
error: unknown;
|
|
37
|
+
sessionId: string;
|
|
38
|
+
status?: TerminalNodeExternalState["status"];
|
|
39
|
+
}
|
|
40
|
+
interface CreateTerminalWorkbenchContributionInput {
|
|
41
|
+
contributionId?: string;
|
|
42
|
+
dockEntry?: Omit<CreateTerminalDockEntryInput, "feature">;
|
|
43
|
+
externalStateSource?: WorkbenchHostExternalStateSource<TerminalNodeExternalState | null, unknown>;
|
|
44
|
+
feature: TerminalNodeFeature;
|
|
45
|
+
getTerminalState?: (sessionId: string) => TerminalNodeExternalState | null;
|
|
46
|
+
node?: Omit<CreateTerminalWorkbenchNodeDefinitionInput, "feature">;
|
|
47
|
+
onCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => void;
|
|
48
|
+
onConfirmClose?: (guard: TerminalCloseGuardResult) => Promise<boolean> | boolean;
|
|
49
|
+
resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;
|
|
50
|
+
shouldCloseAfterCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => boolean;
|
|
51
|
+
typeId?: string;
|
|
52
|
+
}
|
|
53
|
+
declare const defaultTerminalWorkbenchTypeId = "workspace-terminal";
|
|
54
|
+
declare function createTerminalWorkbenchNodeDefinition({ feature, frame, headerAccessory, title, typeId }: CreateTerminalWorkbenchNodeDefinitionInput): WorkbenchHostNodeDefinition<TerminalNodeExternalState>;
|
|
55
|
+
declare function createTerminalDockEntry({ dockIcon, feature, id, order, sectionId, typeId }: CreateTerminalDockEntryInput): WorkbenchHostDockEntry;
|
|
56
|
+
declare function createTerminalWorkbenchLaunchHandler({ feature, frame, resolveLaunchInput, typeId }: CreateTerminalWorkbenchLaunchHandlerInput): (request: WorkbenchHostLaunchRequest) => Promise<WorkbenchHostLaunchResult | null>;
|
|
57
|
+
declare function createTerminalWorkbenchContribution({ contributionId, dockEntry, externalStateSource, feature, getTerminalState, node, onCloseFailure, onConfirmClose, resolveLaunchInput, shouldCloseAfterCloseFailure, typeId }: CreateTerminalWorkbenchContributionInput): WorkbenchContribution;
|
|
58
|
+
|
|
59
|
+
export { type CreateTerminalDockEntryInput, type CreateTerminalWorkbenchContributionInput, type CreateTerminalWorkbenchLaunchHandlerInput, type CreateTerminalWorkbenchNodeDefinitionInput, type TerminalWorkbenchContributionCloseFailure, type TerminalWorkbenchIntent, type TerminalWorkbenchLaunchInputResolver, createTerminalDockEntry, createTerminalWorkbenchContribution, createTerminalWorkbenchLaunchHandler, createTerminalWorkbenchNodeDefinition, defaultTerminalWorkbenchTypeId };
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TerminalNode,
|
|
3
|
+
TerminalNodeHeader,
|
|
4
|
+
acquireTerminalSessionController
|
|
5
|
+
} from "../chunk-FEJT6FJ4.js";
|
|
6
|
+
import {
|
|
7
|
+
closeTerminalSession,
|
|
8
|
+
isTerminalSessionEndedStatus
|
|
9
|
+
} from "../chunk-56B5GYMU.js";
|
|
10
|
+
import "../chunk-65BWWZQV.js";
|
|
11
|
+
|
|
12
|
+
// src/workbench/index.ts
|
|
13
|
+
import { createElement } from "react";
|
|
14
|
+
|
|
15
|
+
// src/workbench/bodyProps.ts
|
|
16
|
+
function resolveTerminalWorkbenchBodyProps({
|
|
17
|
+
context,
|
|
18
|
+
feature
|
|
19
|
+
}) {
|
|
20
|
+
return {
|
|
21
|
+
externalState: context.externalNodeState,
|
|
22
|
+
feature,
|
|
23
|
+
nodeId: context.node.id,
|
|
24
|
+
onFocusRequest: context.isFocused ? void 0 : () => context.focus(),
|
|
25
|
+
sessionId: context.node.data.instanceKey ?? null,
|
|
26
|
+
showHeader: false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/workbench/launchAnalytics.ts
|
|
31
|
+
function resolveTerminalLaunchAnalyticsTrigger(request) {
|
|
32
|
+
switch (request.reason) {
|
|
33
|
+
case "dock":
|
|
34
|
+
return "dock";
|
|
35
|
+
case "launchpad":
|
|
36
|
+
return "launchpad";
|
|
37
|
+
case "shortcut":
|
|
38
|
+
return "keyboard";
|
|
39
|
+
case "host":
|
|
40
|
+
return hasInitialInput(request.payload) ? "agent_command" : "launchpad";
|
|
41
|
+
default:
|
|
42
|
+
return "launchpad";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function hasInitialInput(payload) {
|
|
46
|
+
if (!payload || typeof payload !== "object") {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const typed = payload;
|
|
50
|
+
return typeof typed.initialInput === "string" && typed.initialInput.trim().length > 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/workbench/windowCloseEffect.ts
|
|
54
|
+
async function resolveTerminalWindowCloseEffect({
|
|
55
|
+
closeGuard,
|
|
56
|
+
description,
|
|
57
|
+
externalNodeState,
|
|
58
|
+
nodeId,
|
|
59
|
+
sessionId,
|
|
60
|
+
title,
|
|
61
|
+
typeId
|
|
62
|
+
}) {
|
|
63
|
+
const status = externalNodeState?.status ?? "created";
|
|
64
|
+
if (status === "created" || isTerminalSessionEndedStatus(status)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const resolvedSessionId = sessionId ?? externalNodeState?.sessionId ?? null;
|
|
68
|
+
if (resolvedSessionId) {
|
|
69
|
+
try {
|
|
70
|
+
const guard = await closeGuard.check({ sessionId: resolvedSessionId });
|
|
71
|
+
if (!guard.requiresConfirmation || guard.reason === "not-running" || isTerminalSessionEndedStatus(guard.status)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
description,
|
|
79
|
+
nodeId,
|
|
80
|
+
title: externalNodeState?.title?.trim() || title,
|
|
81
|
+
typeId
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/workbench/index.ts
|
|
86
|
+
var defaultTerminalWorkbenchTypeId = "workspace-terminal";
|
|
87
|
+
var defaultTerminalNodeFrame = {
|
|
88
|
+
height: 520,
|
|
89
|
+
width: 860,
|
|
90
|
+
x: 260,
|
|
91
|
+
y: 140
|
|
92
|
+
};
|
|
93
|
+
function createTerminalWorkbenchNodeDefinition({
|
|
94
|
+
feature,
|
|
95
|
+
frame = defaultTerminalNodeFrame,
|
|
96
|
+
headerAccessory,
|
|
97
|
+
title,
|
|
98
|
+
typeId = defaultTerminalWorkbenchTypeId
|
|
99
|
+
}) {
|
|
100
|
+
return {
|
|
101
|
+
frame,
|
|
102
|
+
instance: {
|
|
103
|
+
mode: "multi"
|
|
104
|
+
},
|
|
105
|
+
renderBody: (context) => createElement(
|
|
106
|
+
TerminalNode,
|
|
107
|
+
resolveTerminalWorkbenchBodyProps({ context, feature })
|
|
108
|
+
),
|
|
109
|
+
createLease: ({ node }) => {
|
|
110
|
+
const sessionId = node.data.instanceKey ?? null;
|
|
111
|
+
if (!sessionId) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const controller = acquireTerminalSessionController({
|
|
115
|
+
feature,
|
|
116
|
+
nodeId: node.id,
|
|
117
|
+
sessionId
|
|
118
|
+
});
|
|
119
|
+
controller.retain();
|
|
120
|
+
return {
|
|
121
|
+
release() {
|
|
122
|
+
controller.release();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
getWindowCloseEffect: ({ externalNodeState, node }) => resolveTerminalWindowCloseEffect({
|
|
127
|
+
closeGuard: feature.closeGuard,
|
|
128
|
+
description: feature.i18n.t("closeGuard.description"),
|
|
129
|
+
externalNodeState,
|
|
130
|
+
nodeId: node.id,
|
|
131
|
+
sessionId: node.data.instanceKey ?? null,
|
|
132
|
+
title: node.title,
|
|
133
|
+
typeId
|
|
134
|
+
}),
|
|
135
|
+
renderHeader: ({
|
|
136
|
+
defaultActions,
|
|
137
|
+
dragHandleProps,
|
|
138
|
+
externalNodeState,
|
|
139
|
+
isFocused,
|
|
140
|
+
node,
|
|
141
|
+
windowActions
|
|
142
|
+
}) => createElement(TerminalNodeHeader, {
|
|
143
|
+
defaultActions,
|
|
144
|
+
externalState: externalNodeState,
|
|
145
|
+
feature,
|
|
146
|
+
headerAccessory,
|
|
147
|
+
onCloseRequest: () => windowActions.close(),
|
|
148
|
+
sessionId: node.data.instanceKey ?? null,
|
|
149
|
+
...dragHandleProps,
|
|
150
|
+
onPointerDown: (event) => {
|
|
151
|
+
dragHandleProps.onPointerDown?.(event);
|
|
152
|
+
if (!isFocused) {
|
|
153
|
+
windowActions.focus();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}),
|
|
157
|
+
title: title ?? feature.i18n.t("title"),
|
|
158
|
+
typeId,
|
|
159
|
+
window: {
|
|
160
|
+
closable: true,
|
|
161
|
+
defaultOpen: false,
|
|
162
|
+
minimizedDock: {
|
|
163
|
+
kind: "snapshot"
|
|
164
|
+
},
|
|
165
|
+
minimizable: true,
|
|
166
|
+
restoreOnLoad: true
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function createTerminalDockEntry({
|
|
171
|
+
dockIcon,
|
|
172
|
+
feature,
|
|
173
|
+
id,
|
|
174
|
+
order,
|
|
175
|
+
sectionId,
|
|
176
|
+
typeId = defaultTerminalWorkbenchTypeId
|
|
177
|
+
}) {
|
|
178
|
+
return {
|
|
179
|
+
icon: dockIcon ?? createElement(DefaultTerminalDockIcon),
|
|
180
|
+
id: id ?? typeId,
|
|
181
|
+
label: feature.i18n.t("dockLabel"),
|
|
182
|
+
launchBehavior: "enabled",
|
|
183
|
+
matchNode: (node) => node.data.typeId === typeId,
|
|
184
|
+
order,
|
|
185
|
+
resolvePopupItem: ({ node }) => ({
|
|
186
|
+
subtitle: node.data.instanceKey ?? node.data.instanceId,
|
|
187
|
+
title: node.title
|
|
188
|
+
}),
|
|
189
|
+
sectionId,
|
|
190
|
+
typeId,
|
|
191
|
+
visibility: "always"
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function createTerminalWorkbenchLaunchHandler({
|
|
195
|
+
feature,
|
|
196
|
+
frame = defaultTerminalNodeFrame,
|
|
197
|
+
resolveLaunchInput,
|
|
198
|
+
typeId = defaultTerminalWorkbenchTypeId
|
|
199
|
+
}) {
|
|
200
|
+
return async (request) => {
|
|
201
|
+
if (request.typeId !== typeId) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const resolved = await resolveLaunchInput?.(request) ?? {};
|
|
205
|
+
const descriptor = await feature.launchService.create({
|
|
206
|
+
cwd: resolved.cwd,
|
|
207
|
+
initialInput: resolved.initialInput,
|
|
208
|
+
profileId: resolved.profileId,
|
|
209
|
+
reason: request.reason === "dock" ? "dock" : "intent",
|
|
210
|
+
workspaceId: request.workspaceId
|
|
211
|
+
});
|
|
212
|
+
return {
|
|
213
|
+
activation: {
|
|
214
|
+
payload: {
|
|
215
|
+
trigger: resolveTerminalLaunchAnalyticsTrigger(request)
|
|
216
|
+
},
|
|
217
|
+
type: "terminal-launch"
|
|
218
|
+
},
|
|
219
|
+
defaultFrame: frame,
|
|
220
|
+
dockEntryId: request.dockEntryId ?? typeId,
|
|
221
|
+
framePolicy: "cascade",
|
|
222
|
+
instanceId: descriptor.sessionId,
|
|
223
|
+
instanceKey: descriptor.sessionId,
|
|
224
|
+
title: descriptor.title,
|
|
225
|
+
typeId
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function createTerminalWorkbenchContribution({
|
|
230
|
+
contributionId,
|
|
231
|
+
dockEntry,
|
|
232
|
+
externalStateSource,
|
|
233
|
+
feature,
|
|
234
|
+
getTerminalState,
|
|
235
|
+
node,
|
|
236
|
+
onCloseFailure,
|
|
237
|
+
onConfirmClose,
|
|
238
|
+
resolveLaunchInput,
|
|
239
|
+
shouldCloseAfterCloseFailure,
|
|
240
|
+
typeId = defaultTerminalWorkbenchTypeId
|
|
241
|
+
}) {
|
|
242
|
+
return {
|
|
243
|
+
dockEntries: [
|
|
244
|
+
createTerminalDockEntry({
|
|
245
|
+
...dockEntry,
|
|
246
|
+
feature,
|
|
247
|
+
typeId
|
|
248
|
+
})
|
|
249
|
+
],
|
|
250
|
+
externalStateSource,
|
|
251
|
+
id: contributionId ?? typeId,
|
|
252
|
+
nodes: [
|
|
253
|
+
createTerminalWorkbenchNodeDefinition({
|
|
254
|
+
...node,
|
|
255
|
+
feature,
|
|
256
|
+
typeId
|
|
257
|
+
})
|
|
258
|
+
],
|
|
259
|
+
onLaunchRequest: createTerminalWorkbenchLaunchHandler({
|
|
260
|
+
feature,
|
|
261
|
+
frame: node?.frame,
|
|
262
|
+
resolveLaunchInput,
|
|
263
|
+
typeId
|
|
264
|
+
}),
|
|
265
|
+
onNodeCloseRequest: onConfirmClose ? (request) => handleTerminalContributionNodeCloseRequest({
|
|
266
|
+
feature,
|
|
267
|
+
getTerminalState,
|
|
268
|
+
onCloseFailure,
|
|
269
|
+
onConfirmClose,
|
|
270
|
+
request,
|
|
271
|
+
shouldCloseAfterCloseFailure,
|
|
272
|
+
typeId
|
|
273
|
+
}) : void 0
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
async function handleTerminalContributionNodeCloseRequest(input) {
|
|
277
|
+
if (input.request.typeId !== input.typeId) {
|
|
278
|
+
return void 0;
|
|
279
|
+
}
|
|
280
|
+
const sessionId = input.request.instanceKey ?? input.request.instanceId;
|
|
281
|
+
const terminalState = input.getTerminalState?.(sessionId) ?? null;
|
|
282
|
+
try {
|
|
283
|
+
const result = await closeTerminalSession({
|
|
284
|
+
confirm: input.onConfirmClose,
|
|
285
|
+
feature: input.feature,
|
|
286
|
+
sessionId,
|
|
287
|
+
status: terminalState?.status
|
|
288
|
+
});
|
|
289
|
+
return result === "closed" ? "close" : "keep-open";
|
|
290
|
+
} catch (error) {
|
|
291
|
+
const failure = {
|
|
292
|
+
error,
|
|
293
|
+
sessionId,
|
|
294
|
+
status: terminalState?.status
|
|
295
|
+
};
|
|
296
|
+
input.onCloseFailure?.(failure);
|
|
297
|
+
return input.shouldCloseAfterCloseFailure?.(failure) ? "close" : "keep-open";
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function DefaultTerminalDockIcon() {
|
|
301
|
+
return createElement(
|
|
302
|
+
"span",
|
|
303
|
+
{
|
|
304
|
+
"aria-hidden": "true",
|
|
305
|
+
className: "workspace-terminal__dock-icon"
|
|
306
|
+
},
|
|
307
|
+
">"
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
export {
|
|
311
|
+
createTerminalDockEntry,
|
|
312
|
+
createTerminalWorkbenchContribution,
|
|
313
|
+
createTerminalWorkbenchLaunchHandler,
|
|
314
|
+
createTerminalWorkbenchNodeDefinition,
|
|
315
|
+
defaultTerminalWorkbenchTypeId
|
|
316
|
+
};
|
|
317
|
+
//# sourceMappingURL=index.js.map
|