@pellux/goodvibes-sdk 0.18.20 → 0.18.22
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/dist/_internal/platform/automation/manager-runtime-execution.d.ts +2 -0
- package/dist/_internal/platform/automation/manager-runtime-execution.d.ts.map +1 -1
- package/dist/_internal/platform/automation/manager-runtime-execution.js +18 -6
- package/dist/_internal/platform/automation/manager-runtime.d.ts +5 -0
- package/dist/_internal/platform/automation/manager-runtime.d.ts.map +1 -1
- package/dist/_internal/platform/automation/manager-runtime.js +6 -0
- package/dist/_internal/platform/core/deterministic-replay.d.ts +2 -1
- package/dist/_internal/platform/core/deterministic-replay.d.ts.map +1 -1
- package/dist/_internal/platform/core/deterministic-replay.js +11 -5
- package/dist/_internal/platform/core/replay-command-handler.js +1 -1
- package/dist/_internal/platform/plugins/api.d.ts +2 -2
- package/dist/_internal/platform/plugins/api.d.ts.map +1 -1
- package/dist/_internal/platform/plugins/loader.d.ts +2 -2
- package/dist/_internal/platform/plugins/loader.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/host-ui.d.ts +59 -0
- package/dist/_internal/platform/runtime/host-ui.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/host-ui.js +25 -0
- package/dist/_internal/platform/runtime/integration/helpers.d.ts +2 -2
- package/dist/_internal/platform/runtime/integration/helpers.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/services.d.ts +5 -4
- package/dist/_internal/platform/runtime/services.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/services.js +5 -6
- package/package.json +1 -1
- package/dist/_internal/platform/input/command-registry.d.ts +0 -17
- package/dist/_internal/platform/input/command-registry.d.ts.map +0 -1
- package/dist/_internal/platform/input/command-registry.js +0 -25
- package/dist/_internal/platform/input/keybindings.d.ts +0 -88
- package/dist/_internal/platform/input/keybindings.d.ts.map +0 -1
- package/dist/_internal/platform/input/keybindings.js +0 -206
- package/dist/_internal/platform/panels/panel-manager.d.ts +0 -89
- package/dist/_internal/platform/panels/panel-manager.d.ts.map +0 -1
- package/dist/_internal/platform/panels/panel-manager.js +0 -481
- package/dist/_internal/platform/panels/types.d.ts +0 -30
- package/dist/_internal/platform/panels/types.d.ts.map +0 -1
- package/dist/_internal/platform/panels/types.js +0 -1
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// PanelManager — central manager for panel lifecycle, navigation, and split
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// PanelManager
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
export class PanelManager {
|
|
8
|
-
registry = [];
|
|
9
|
-
retainedPanels = new Map();
|
|
10
|
-
_visible = false;
|
|
11
|
-
_splitRatio = 0.6;
|
|
12
|
-
// Two panes for the top/bottom split within the panel area
|
|
13
|
-
topPane = { panels: [], activeIndex: 0 };
|
|
14
|
-
bottomPane = { panels: [], activeIndex: 0 };
|
|
15
|
-
_focusedPane = 'top';
|
|
16
|
-
_verticalSplitRatio = 0.5; // top gets 50% of panel height
|
|
17
|
-
_bottomPaneVisible = false;
|
|
18
|
-
// -------------------------------------------------------------------------
|
|
19
|
-
// Registration
|
|
20
|
-
// -------------------------------------------------------------------------
|
|
21
|
-
registerType(registration) {
|
|
22
|
-
const existing = this.registry.findIndex(r => r.id === registration.id);
|
|
23
|
-
if (existing >= 0) {
|
|
24
|
-
this.registry[existing] = registration;
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
this.registry.push(registration);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
getRegisteredTypes() {
|
|
31
|
-
return [...this.registry];
|
|
32
|
-
}
|
|
33
|
-
getTypesByCategory() {
|
|
34
|
-
const map = new Map();
|
|
35
|
-
for (const reg of this.registry) {
|
|
36
|
-
const list = map.get(reg.category) ?? [];
|
|
37
|
-
list.push(reg);
|
|
38
|
-
map.set(reg.category, list);
|
|
39
|
-
}
|
|
40
|
-
return map;
|
|
41
|
-
}
|
|
42
|
-
prewarmRegistered() {
|
|
43
|
-
for (const registration of this.registry) {
|
|
44
|
-
if (!registration.preload)
|
|
45
|
-
continue;
|
|
46
|
-
if (this.getPanel(registration.id) || this.retainedPanels.has(registration.id))
|
|
47
|
-
continue;
|
|
48
|
-
const panel = registration.factory();
|
|
49
|
-
this.retainedPanels.set(registration.id, panel);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// -------------------------------------------------------------------------
|
|
53
|
-
// Panel lifecycle — operates on a specific pane (defaults to focused)
|
|
54
|
-
// -------------------------------------------------------------------------
|
|
55
|
-
open(panelId, pane) {
|
|
56
|
-
const existingPane = this._findPaneOf(panelId);
|
|
57
|
-
if (existingPane) {
|
|
58
|
-
this._activateByIdInPane(panelId, existingPane);
|
|
59
|
-
this._visible = true;
|
|
60
|
-
this._focusedPane = existingPane;
|
|
61
|
-
if (existingPane === 'bottom')
|
|
62
|
-
this._bottomPaneVisible = true;
|
|
63
|
-
return this._getPane(existingPane).panels[this._getPane(existingPane).activeIndex];
|
|
64
|
-
}
|
|
65
|
-
const targetPane = pane ?? this._focusedPane;
|
|
66
|
-
const p = this._getPane(targetPane);
|
|
67
|
-
const oldPanel = p.panels[p.activeIndex];
|
|
68
|
-
if (oldPanel)
|
|
69
|
-
oldPanel.onDeactivate();
|
|
70
|
-
const panel = this._obtainPanel(panelId);
|
|
71
|
-
p.panels.push(panel);
|
|
72
|
-
p.activeIndex = p.panels.length - 1;
|
|
73
|
-
this._visible = true;
|
|
74
|
-
// If opening into bottom pane, also make it visible
|
|
75
|
-
if (targetPane === 'bottom') {
|
|
76
|
-
this._bottomPaneVisible = true;
|
|
77
|
-
this._focusedPane = 'bottom';
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
this._focusedPane = 'top';
|
|
81
|
-
}
|
|
82
|
-
panel.onActivate();
|
|
83
|
-
return panel;
|
|
84
|
-
}
|
|
85
|
-
close(panelId) {
|
|
86
|
-
// Search both panes
|
|
87
|
-
for (const which of ['top', 'bottom']) {
|
|
88
|
-
const p = this._getPane(which);
|
|
89
|
-
const index = p.panels.findIndex(panel => panel.id === panelId);
|
|
90
|
-
if (index < 0)
|
|
91
|
-
continue;
|
|
92
|
-
const panel = p.panels[index];
|
|
93
|
-
const wasActive = index === p.activeIndex;
|
|
94
|
-
if (wasActive)
|
|
95
|
-
panel.onDeactivate();
|
|
96
|
-
if (this._shouldRetain(panelId)) {
|
|
97
|
-
this.retainedPanels.set(panelId, panel);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
panel.onDestroy();
|
|
101
|
-
}
|
|
102
|
-
p.panels.splice(index, 1);
|
|
103
|
-
if (p.panels.length === 0) {
|
|
104
|
-
p.activeIndex = 0;
|
|
105
|
-
if (which === 'bottom') {
|
|
106
|
-
this._bottomPaneVisible = false;
|
|
107
|
-
// Move focus to top if we were focused on empty bottom
|
|
108
|
-
if (this._focusedPane === 'bottom')
|
|
109
|
-
this._focusedPane = 'top';
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
p.activeIndex = Math.min(p.activeIndex, p.panels.length - 1);
|
|
114
|
-
if (wasActive) {
|
|
115
|
-
const newActive = p.panels[p.activeIndex];
|
|
116
|
-
if (newActive)
|
|
117
|
-
newActive.onActivate();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Hide sidebar if no panels remain in either pane
|
|
121
|
-
if (this.topPane.panels.length === 0 && this.bottomPane.panels.length === 0) {
|
|
122
|
-
this._visible = false;
|
|
123
|
-
}
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Move a panel to a specific pane. If panelId is omitted, moves the active
|
|
129
|
-
* panel from the currently focused pane.
|
|
130
|
-
*/
|
|
131
|
-
moveToPane(dest, panelId) {
|
|
132
|
-
const srcPaneName = panelId
|
|
133
|
-
? this._findPaneOf(panelId) ?? this._focusedPane
|
|
134
|
-
: this._focusedPane;
|
|
135
|
-
if (srcPaneName === dest)
|
|
136
|
-
return; // already there
|
|
137
|
-
const dstPaneName = dest;
|
|
138
|
-
this._moveBetweenPanes(srcPaneName, dstPaneName, panelId);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Move a panel to the other pane. If panelId is omitted, moves the active
|
|
142
|
-
* panel from the currently focused pane.
|
|
143
|
-
*/
|
|
144
|
-
moveToOtherPane(panelId) {
|
|
145
|
-
const srcPaneName = panelId
|
|
146
|
-
? this._findPaneOf(panelId) ?? this._focusedPane
|
|
147
|
-
: this._focusedPane;
|
|
148
|
-
const dstPaneName = srcPaneName === 'top' ? 'bottom' : 'top';
|
|
149
|
-
this._moveBetweenPanes(srcPaneName, dstPaneName, panelId);
|
|
150
|
-
}
|
|
151
|
-
// -------------------------------------------------------------------------
|
|
152
|
-
// Navigation — operates on focused pane
|
|
153
|
-
// -------------------------------------------------------------------------
|
|
154
|
-
nextPanel() {
|
|
155
|
-
const p = this._getFocusedPane();
|
|
156
|
-
if (p.panels.length === 0)
|
|
157
|
-
return;
|
|
158
|
-
const oldPanel = p.panels[p.activeIndex];
|
|
159
|
-
if (oldPanel)
|
|
160
|
-
oldPanel.onDeactivate();
|
|
161
|
-
p.activeIndex = (p.activeIndex + 1) % p.panels.length;
|
|
162
|
-
const newPanel = p.panels[p.activeIndex];
|
|
163
|
-
if (newPanel)
|
|
164
|
-
newPanel.onActivate();
|
|
165
|
-
}
|
|
166
|
-
nextWorkspaceTab() {
|
|
167
|
-
this._cycleWorkspaceTab(1);
|
|
168
|
-
}
|
|
169
|
-
prevWorkspaceTab() {
|
|
170
|
-
this._cycleWorkspaceTab(-1);
|
|
171
|
-
}
|
|
172
|
-
prevPanel() {
|
|
173
|
-
const p = this._getFocusedPane();
|
|
174
|
-
if (p.panels.length === 0)
|
|
175
|
-
return;
|
|
176
|
-
const oldPanel = p.panels[p.activeIndex];
|
|
177
|
-
if (oldPanel)
|
|
178
|
-
oldPanel.onDeactivate();
|
|
179
|
-
p.activeIndex = (p.activeIndex - 1 + p.panels.length) % p.panels.length;
|
|
180
|
-
const newPanel = p.panels[p.activeIndex];
|
|
181
|
-
if (newPanel)
|
|
182
|
-
newPanel.onActivate();
|
|
183
|
-
}
|
|
184
|
-
activateByIndex(index) {
|
|
185
|
-
const p = this._getFocusedPane();
|
|
186
|
-
if (index < 0 || index >= p.panels.length)
|
|
187
|
-
return;
|
|
188
|
-
if (index === p.activeIndex)
|
|
189
|
-
return;
|
|
190
|
-
const oldPanel = p.panels[p.activeIndex];
|
|
191
|
-
if (oldPanel)
|
|
192
|
-
oldPanel.onDeactivate();
|
|
193
|
-
p.activeIndex = index;
|
|
194
|
-
const newPanel = p.panels[p.activeIndex];
|
|
195
|
-
if (newPanel)
|
|
196
|
-
newPanel.onActivate();
|
|
197
|
-
}
|
|
198
|
-
activateById(panelId) {
|
|
199
|
-
const which = this._findPaneOf(panelId);
|
|
200
|
-
if (!which)
|
|
201
|
-
return;
|
|
202
|
-
this._activateByIdInPane(panelId, which);
|
|
203
|
-
}
|
|
204
|
-
// -------------------------------------------------------------------------
|
|
205
|
-
// Pane focus control
|
|
206
|
-
// -------------------------------------------------------------------------
|
|
207
|
-
focusPane(pane) {
|
|
208
|
-
if (pane === 'bottom' && !this._bottomPaneVisible)
|
|
209
|
-
return;
|
|
210
|
-
this._focusedPane = pane;
|
|
211
|
-
}
|
|
212
|
-
getFocusedPane() {
|
|
213
|
-
return this._focusedPane;
|
|
214
|
-
}
|
|
215
|
-
/** Get the currently active (focused) panel, or null if none. */
|
|
216
|
-
getActivePanel() {
|
|
217
|
-
const p = this._getFocusedPane();
|
|
218
|
-
return p.panels[p.activeIndex] ?? null;
|
|
219
|
-
}
|
|
220
|
-
togglePaneFocus() {
|
|
221
|
-
if (!this._bottomPaneVisible || this.bottomPane.panels.length === 0)
|
|
222
|
-
return;
|
|
223
|
-
this._focusedPane = this._focusedPane === 'top' ? 'bottom' : 'top';
|
|
224
|
-
}
|
|
225
|
-
// -------------------------------------------------------------------------
|
|
226
|
-
// Pane visibility
|
|
227
|
-
// -------------------------------------------------------------------------
|
|
228
|
-
toggleBottomPane() {
|
|
229
|
-
if (this._bottomPaneVisible) {
|
|
230
|
-
this._bottomPaneVisible = false;
|
|
231
|
-
if (this._focusedPane === 'bottom')
|
|
232
|
-
this._focusedPane = 'top';
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
this._bottomPaneVisible = true;
|
|
236
|
-
// If bottom pane is empty, populate it
|
|
237
|
-
if (this.bottomPane.panels.length === 0) {
|
|
238
|
-
if (this.topPane.panels.length > 1) {
|
|
239
|
-
// Move last panel from top to bottom
|
|
240
|
-
const panel = this.topPane.panels.pop();
|
|
241
|
-
if (this.topPane.activeIndex >= this.topPane.panels.length) {
|
|
242
|
-
this.topPane.activeIndex = Math.max(0, this.topPane.panels.length - 1);
|
|
243
|
-
}
|
|
244
|
-
this.bottomPane.panels.push(panel);
|
|
245
|
-
this.bottomPane.activeIndex = 0;
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
// Open a default panel in bottom pane
|
|
249
|
-
const firstType = this.registry[0];
|
|
250
|
-
if (firstType) {
|
|
251
|
-
this.open(firstType.id, 'bottom');
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
this._focusedPane = 'bottom';
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
isBottomPaneVisible() {
|
|
259
|
-
return this._bottomPaneVisible && this.bottomPane.panels.length > 0;
|
|
260
|
-
}
|
|
261
|
-
// -------------------------------------------------------------------------
|
|
262
|
-
// Pane state accessors
|
|
263
|
-
// -------------------------------------------------------------------------
|
|
264
|
-
getTopPane() {
|
|
265
|
-
return this.topPane;
|
|
266
|
-
}
|
|
267
|
-
getBottomPane() {
|
|
268
|
-
return this.bottomPane;
|
|
269
|
-
}
|
|
270
|
-
// -------------------------------------------------------------------------
|
|
271
|
-
// Backward-compatible accessors (operate on focused pane)
|
|
272
|
-
// -------------------------------------------------------------------------
|
|
273
|
-
getOpen() {
|
|
274
|
-
const p = this._getFocusedPane();
|
|
275
|
-
return [...p.panels];
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Returns all panels across both panes (top then bottom).
|
|
279
|
-
* Use this when you need to know if any panels exist at all.
|
|
280
|
-
*/
|
|
281
|
-
getAllOpen() {
|
|
282
|
-
return [...this.topPane.panels, ...this.bottomPane.panels];
|
|
283
|
-
}
|
|
284
|
-
getActive() {
|
|
285
|
-
const p = this._getFocusedPane();
|
|
286
|
-
if (p.panels.length === 0)
|
|
287
|
-
return null;
|
|
288
|
-
return p.panels[p.activeIndex] ?? null;
|
|
289
|
-
}
|
|
290
|
-
getPanel(panelId) {
|
|
291
|
-
return this.topPane.panels.find((panel) => panel.id === panelId)
|
|
292
|
-
?? this.bottomPane.panels.find((panel) => panel.id === panelId)
|
|
293
|
-
?? null;
|
|
294
|
-
}
|
|
295
|
-
getPaneOf(panelId) {
|
|
296
|
-
return this._findPaneOf(panelId);
|
|
297
|
-
}
|
|
298
|
-
getWorkspaceTabs() {
|
|
299
|
-
const focusedPanelId = this.getActivePanel()?.id;
|
|
300
|
-
const topTabs = this.topPane.panels.map((panel) => ({
|
|
301
|
-
id: panel.id,
|
|
302
|
-
name: panel.name,
|
|
303
|
-
icon: panel.icon,
|
|
304
|
-
pane: 'top',
|
|
305
|
-
active: panel.id === focusedPanelId,
|
|
306
|
-
focused: panel.id === focusedPanelId,
|
|
307
|
-
}));
|
|
308
|
-
const bottomTabs = this.bottomPane.panels.map((panel) => ({
|
|
309
|
-
id: panel.id,
|
|
310
|
-
name: panel.name,
|
|
311
|
-
icon: panel.icon,
|
|
312
|
-
pane: 'bottom',
|
|
313
|
-
active: panel.id === focusedPanelId,
|
|
314
|
-
focused: panel.id === focusedPanelId,
|
|
315
|
-
}));
|
|
316
|
-
return [...topTabs, ...bottomTabs];
|
|
317
|
-
}
|
|
318
|
-
activateWorkspaceIndex(index) {
|
|
319
|
-
const tabs = this.getWorkspaceTabs();
|
|
320
|
-
if (index < 0 || index >= tabs.length)
|
|
321
|
-
return;
|
|
322
|
-
const tab = tabs[index];
|
|
323
|
-
this._focusedPane = tab.pane;
|
|
324
|
-
if (tab.pane === 'bottom')
|
|
325
|
-
this._bottomPaneVisible = true;
|
|
326
|
-
this._activateByIdInPane(tab.id, tab.pane);
|
|
327
|
-
}
|
|
328
|
-
// -------------------------------------------------------------------------
|
|
329
|
-
// Visibility
|
|
330
|
-
// -------------------------------------------------------------------------
|
|
331
|
-
toggle() {
|
|
332
|
-
this._visible = !this._visible;
|
|
333
|
-
// Auto-open a default panel if toggling visible with nothing open
|
|
334
|
-
if (this._visible && this.topPane.panels.length === 0 && this.bottomPane.panels.length === 0) {
|
|
335
|
-
const defaultPanel = this._getRegistration('panel-list') ?? this.registry[0];
|
|
336
|
-
if (defaultPanel)
|
|
337
|
-
this.open(defaultPanel.id);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
show() {
|
|
341
|
-
this._visible = true;
|
|
342
|
-
}
|
|
343
|
-
hide() {
|
|
344
|
-
this._visible = false;
|
|
345
|
-
}
|
|
346
|
-
isVisible() {
|
|
347
|
-
return this._visible;
|
|
348
|
-
}
|
|
349
|
-
// -------------------------------------------------------------------------
|
|
350
|
-
// Horizontal split control (left/right)
|
|
351
|
-
// -------------------------------------------------------------------------
|
|
352
|
-
getSplitRatio() {
|
|
353
|
-
return this._splitRatio;
|
|
354
|
-
}
|
|
355
|
-
setSplitRatio(ratio) {
|
|
356
|
-
this._splitRatio = Math.max(0.3, Math.min(0.85, ratio));
|
|
357
|
-
}
|
|
358
|
-
widenLeft() {
|
|
359
|
-
this.setSplitRatio(this._splitRatio + 0.05);
|
|
360
|
-
}
|
|
361
|
-
widenRight() {
|
|
362
|
-
this.setSplitRatio(this._splitRatio - 0.05);
|
|
363
|
-
}
|
|
364
|
-
getLeftWidth(totalWidth) {
|
|
365
|
-
return Math.floor(totalWidth * this._splitRatio);
|
|
366
|
-
}
|
|
367
|
-
getRightWidth(totalWidth) {
|
|
368
|
-
return totalWidth - this.getLeftWidth(totalWidth);
|
|
369
|
-
}
|
|
370
|
-
// -------------------------------------------------------------------------
|
|
371
|
-
// Vertical split control (top/bottom within panel area)
|
|
372
|
-
// -------------------------------------------------------------------------
|
|
373
|
-
getVerticalSplitRatio() {
|
|
374
|
-
return this._verticalSplitRatio;
|
|
375
|
-
}
|
|
376
|
-
setVerticalSplitRatio(ratio) {
|
|
377
|
-
this._verticalSplitRatio = Math.max(0.2, Math.min(0.8, ratio));
|
|
378
|
-
}
|
|
379
|
-
// -------------------------------------------------------------------------
|
|
380
|
-
// Cleanup
|
|
381
|
-
// -------------------------------------------------------------------------
|
|
382
|
-
destroyAll() {
|
|
383
|
-
for (const panel of [...this.topPane.panels, ...this.bottomPane.panels, ...this.retainedPanels.values()]) {
|
|
384
|
-
panel.onDestroy();
|
|
385
|
-
}
|
|
386
|
-
this.topPane = { panels: [], activeIndex: 0 };
|
|
387
|
-
this.bottomPane = { panels: [], activeIndex: 0 };
|
|
388
|
-
this.retainedPanels.clear();
|
|
389
|
-
this.registry = [];
|
|
390
|
-
this._focusedPane = 'top';
|
|
391
|
-
this._bottomPaneVisible = false;
|
|
392
|
-
this._visible = false;
|
|
393
|
-
}
|
|
394
|
-
// -------------------------------------------------------------------------
|
|
395
|
-
// Private helpers
|
|
396
|
-
// -------------------------------------------------------------------------
|
|
397
|
-
_getPane(which) {
|
|
398
|
-
return which === 'top' ? this.topPane : this.bottomPane;
|
|
399
|
-
}
|
|
400
|
-
_getFocusedPane() {
|
|
401
|
-
return this._getPane(this._focusedPane);
|
|
402
|
-
}
|
|
403
|
-
_findPaneOf(panelId) {
|
|
404
|
-
if (this.topPane.panels.some(p => p.id === panelId))
|
|
405
|
-
return 'top';
|
|
406
|
-
if (this.bottomPane.panels.some(p => p.id === panelId))
|
|
407
|
-
return 'bottom';
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
_moveBetweenPanes(srcPaneName, dstPaneName, panelId) {
|
|
411
|
-
const src = this._getPane(srcPaneName);
|
|
412
|
-
const dst = this._getPane(dstPaneName);
|
|
413
|
-
const id = panelId ?? src.panels[src.activeIndex]?.id;
|
|
414
|
-
if (!id)
|
|
415
|
-
return;
|
|
416
|
-
const index = src.panels.findIndex(p => p.id === id);
|
|
417
|
-
if (index < 0)
|
|
418
|
-
return;
|
|
419
|
-
const panel = src.panels[index];
|
|
420
|
-
const wasActive = index === src.activeIndex;
|
|
421
|
-
if (wasActive)
|
|
422
|
-
panel.onDeactivate();
|
|
423
|
-
src.panels.splice(index, 1);
|
|
424
|
-
src.activeIndex = Math.min(src.activeIndex, Math.max(0, src.panels.length - 1));
|
|
425
|
-
if (wasActive && src.panels.length > 0) {
|
|
426
|
-
src.panels[src.activeIndex]?.onActivate();
|
|
427
|
-
}
|
|
428
|
-
// Deactivate current active in dest
|
|
429
|
-
const oldDstActive = dst.panels[dst.activeIndex];
|
|
430
|
-
if (oldDstActive)
|
|
431
|
-
oldDstActive.onDeactivate();
|
|
432
|
-
dst.panels.push(panel);
|
|
433
|
-
dst.activeIndex = dst.panels.length - 1;
|
|
434
|
-
panel.onActivate();
|
|
435
|
-
if (dstPaneName === 'bottom') {
|
|
436
|
-
this._bottomPaneVisible = true;
|
|
437
|
-
}
|
|
438
|
-
this._focusedPane = dstPaneName;
|
|
439
|
-
}
|
|
440
|
-
_cycleWorkspaceTab(direction) {
|
|
441
|
-
const tabs = this.getWorkspaceTabs();
|
|
442
|
-
if (tabs.length === 0)
|
|
443
|
-
return;
|
|
444
|
-
const currentIndex = tabs.findIndex((tab) => tab.focused);
|
|
445
|
-
const nextIndex = currentIndex < 0
|
|
446
|
-
? 0
|
|
447
|
-
: (currentIndex + direction + tabs.length) % tabs.length;
|
|
448
|
-
this.activateWorkspaceIndex(nextIndex);
|
|
449
|
-
}
|
|
450
|
-
_obtainPanel(panelId) {
|
|
451
|
-
const retained = this.retainedPanels.get(panelId);
|
|
452
|
-
if (retained) {
|
|
453
|
-
this.retainedPanels.delete(panelId);
|
|
454
|
-
return retained;
|
|
455
|
-
}
|
|
456
|
-
const registration = this._getRegistration(panelId);
|
|
457
|
-
if (!registration) {
|
|
458
|
-
throw new Error(`No panel type registered with id: ${panelId}`);
|
|
459
|
-
}
|
|
460
|
-
return registration.factory();
|
|
461
|
-
}
|
|
462
|
-
_getRegistration(panelId) {
|
|
463
|
-
return this.registry.find((registration) => registration.id === panelId);
|
|
464
|
-
}
|
|
465
|
-
_shouldRetain(panelId) {
|
|
466
|
-
return this._getRegistration(panelId)?.preload === true;
|
|
467
|
-
}
|
|
468
|
-
_activateByIdInPane(panelId, which) {
|
|
469
|
-
const p = this._getPane(which);
|
|
470
|
-
const index = p.panels.findIndex(panel => panel.id === panelId);
|
|
471
|
-
if (index >= 0 && index !== p.activeIndex) {
|
|
472
|
-
const oldPanel = p.panels[p.activeIndex];
|
|
473
|
-
if (oldPanel)
|
|
474
|
-
oldPanel.onDeactivate();
|
|
475
|
-
p.activeIndex = index;
|
|
476
|
-
const newPanel = p.panels[p.activeIndex];
|
|
477
|
-
if (newPanel)
|
|
478
|
-
newPanel.onActivate();
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { Line } from '@pellux/goodvibes-sdk/platform/types/grid';
|
|
2
|
-
import type { PanelResourceContract, PanelHealthState } from '@pellux/goodvibes-sdk/platform/runtime/perf/panel-contracts';
|
|
3
|
-
export type PanelCategory = 'development' | 'agent' | 'monitoring' | 'session' | 'ai';
|
|
4
|
-
export interface Panel {
|
|
5
|
-
id: string;
|
|
6
|
-
name: string;
|
|
7
|
-
icon: string;
|
|
8
|
-
category: PanelCategory;
|
|
9
|
-
onActivate(): void;
|
|
10
|
-
onDeactivate(): void;
|
|
11
|
-
onDestroy(): void;
|
|
12
|
-
render(width: number, height: number): Line[];
|
|
13
|
-
isTransient: boolean;
|
|
14
|
-
isPinned: boolean;
|
|
15
|
-
needsRender: boolean;
|
|
16
|
-
resourceContract?: Readonly<PanelResourceContract>;
|
|
17
|
-
healthState?: Readonly<PanelHealthState>;
|
|
18
|
-
handleInput?(key: string): boolean;
|
|
19
|
-
}
|
|
20
|
-
export interface PanelRegistration extends Pick<Panel, 'id' | 'name' | 'icon' | 'category'> {
|
|
21
|
-
factory: () => Panel;
|
|
22
|
-
description: string;
|
|
23
|
-
/**
|
|
24
|
-
* Instantiate this panel during bootstrap and retain the instance when it is
|
|
25
|
-
* closed so its background data continues to accumulate before the user
|
|
26
|
-
* actively opens the workspace.
|
|
27
|
-
*/
|
|
28
|
-
preload?: boolean;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/panels/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,6DAA6D,CAAC;AAE3H,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,IAAI,CAAC;AAEtF,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IAGxB,UAAU,IAAI,IAAI,CAAC;IACnB,YAAY,IAAI,IAAI,CAAC;IACrB,SAAS,IAAI,IAAI,CAAC;IAGlB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC;IAG9C,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IAGrB,gBAAgB,CAAC,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAGnD,WAAW,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAGzC,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IACzF,OAAO,EAAE,MAAM,KAAK,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|