tmux-ide 2.9.0-beta.20 → 2.9.0-beta.21
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/bin/cli.js +100 -8
- package/package.json +3 -2
- package/packages/daemon/dist/command-center/diagnostics.js +65 -0
- package/packages/daemon/dist/command-center/log-stream.js +9 -0
- package/packages/daemon/dist/command-center/server.js +7 -0
- package/packages/daemon/dist/lib/app-config.js +4 -2
- package/packages/daemon/dist/lib/soak-diagnostics.js +124 -0
- package/packages/daemon/dist/lib/soak-verdict.js +185 -35
- package/packages/daemon/dist/lib/terminal-host-color.js +33 -0
- package/packages/daemon/dist/tui/mirror/automatic-contrast.js +161 -0
- package/packages/daemon/dist/tui/mirror/open-tui-workspace-runtime-port.js +9 -3
- package/packages/daemon/dist/tui/mirror/pane-surface.jsx +7 -5
- package/packages/daemon/dist/tui/mirror/resize-transaction.js +48 -20
- package/packages/daemon/dist/tui/mirror/runtime/application-appearance-owner.js +40 -6
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +63 -42
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +138 -67
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-palette-owner.js +44 -28
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace.jsx +49 -11
- package/packages/daemon/dist/tui/mirror/runtime/semantic-shell-viewport-resize.js +140 -2
- package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +3 -1
- package/packages/daemon/dist/tui/mirror/semantic-pane-render-source.js +2 -1
- package/packages/daemon/dist/tui/mirror/theme.js +4 -31
- package/packages/daemon/dist/tui/mirror/workspace/terminal-pane-header.jsx +15 -8
- package/packages/daemon/src/command-center/diagnostics.ts +75 -0
- package/packages/daemon/src/command-center/log-stream.ts +8 -0
- package/packages/daemon/src/command-center/server.ts +8 -0
- package/packages/daemon/src/lib/app-config.ts +11 -3
- package/packages/daemon/src/lib/soak-diagnostics.ts +183 -0
- package/packages/daemon/src/lib/soak-verdict.ts +314 -23
- package/packages/daemon/src/lib/terminal-host-color.ts +43 -0
- package/packages/daemon/src/tui/mirror/automatic-contrast.ts +180 -0
- package/packages/daemon/src/tui/mirror/open-tui-workspace-runtime-port.ts +26 -5
- package/packages/daemon/src/tui/mirror/pane-surface.tsx +9 -8
- package/packages/daemon/src/tui/mirror/resize-transaction.ts +46 -22
- package/packages/daemon/src/tui/mirror/runtime/application-appearance-owner.ts +45 -6
- package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +99 -75
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +1 -0
- package/packages/daemon/src/tui/mirror/runtime/application-shell-overlays.tsx +9 -2
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +2 -0
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +148 -69
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-palette-owner.ts +55 -28
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace.tsx +59 -17
- package/packages/daemon/src/tui/mirror/runtime/semantic-shell-viewport-resize.ts +151 -3
- package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +3 -1
- package/packages/daemon/src/tui/mirror/semantic-pane-render-source.ts +2 -1
- package/packages/daemon/src/tui/mirror/theme.ts +4 -39
- package/packages/daemon/src/tui/mirror/workspace/terminal-pane-header.tsx +21 -8
- package/packages/daemon-client/src/terminal-fast-lane.test.ts +18 -0
- package/packages/daemon-client/src/terminal-fast-lane.ts +7 -2
|
@@ -12,6 +12,7 @@ function nonEmpty(value, label) {
|
|
|
12
12
|
}
|
|
13
13
|
function sameTarget(state, observation) {
|
|
14
14
|
return (state.operationId === observation.operationId &&
|
|
15
|
+
state.authorityGeneration === observation.authorityGeneration &&
|
|
15
16
|
state.workspaceName === observation.workspaceName &&
|
|
16
17
|
state.semanticPaneId === observation.semanticPaneId &&
|
|
17
18
|
state.axis === observation.axis);
|
|
@@ -19,9 +20,9 @@ function sameTarget(state, observation) {
|
|
|
19
20
|
/**
|
|
20
21
|
* Renderer-local pane-resize transaction.
|
|
21
22
|
*
|
|
22
|
-
* Pointer motion
|
|
23
|
-
*
|
|
24
|
-
* operation
|
|
23
|
+
* Pointer motion submits the first target immediately, then retains only the
|
|
24
|
+
* latest desired size while receipt and canonical layout settle the pending
|
|
25
|
+
* operation. Release closes the gesture and flushes that latest target. The controller owns no timers, transport, or
|
|
25
26
|
* rendering effects beyond the functions supplied by its caller.
|
|
26
27
|
*/
|
|
27
28
|
export class ResizeTransactionController {
|
|
@@ -35,6 +36,8 @@ export class ResizeTransactionController {
|
|
|
35
36
|
#projection = null;
|
|
36
37
|
#revision = 0;
|
|
37
38
|
#disposed = false;
|
|
39
|
+
#dragOpen = false;
|
|
40
|
+
#submittedCells = null;
|
|
38
41
|
constructor(options) {
|
|
39
42
|
if (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0) {
|
|
40
43
|
throw new RangeError("resize transaction timeout must be positive");
|
|
@@ -54,6 +57,8 @@ export class ResizeTransactionController {
|
|
|
54
57
|
const workspaceName = nonEmpty(input.workspaceName, "workspaceName");
|
|
55
58
|
const semanticPaneId = nonEmpty(input.semanticPaneId, "semanticPaneId");
|
|
56
59
|
const canonicalCells = positiveCells(input.canonicalCells, "canonicalCells");
|
|
60
|
+
this.#dragOpen = true;
|
|
61
|
+
this.#submittedCells = null;
|
|
57
62
|
this.#projection = createOptimisticProjection({
|
|
58
63
|
generation: authorityGeneration,
|
|
59
64
|
revision: this.#revision,
|
|
@@ -71,30 +76,36 @@ export class ResizeTransactionController {
|
|
|
71
76
|
});
|
|
72
77
|
return true;
|
|
73
78
|
}
|
|
74
|
-
/**
|
|
79
|
+
/** First/latest coalescing: at most one mutation awaits canonical settlement. */
|
|
75
80
|
move(previewCells) {
|
|
76
|
-
if (this.#state.phase
|
|
81
|
+
if (!this.#dragOpen || this.#state.phase === "idle")
|
|
77
82
|
return false;
|
|
78
83
|
const next = positiveCells(previewCells, "previewCells");
|
|
79
84
|
if (next === this.#state.previewCells)
|
|
80
85
|
return false;
|
|
81
86
|
this.#emit({ ...this.#state, previewCells: next });
|
|
87
|
+
if (this.#state.phase === "dragging")
|
|
88
|
+
this.#submit();
|
|
82
89
|
return true;
|
|
83
90
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Submit once. Duplicate physical release/up/drop events return the existing
|
|
86
|
-
* operation id without authoring another mutation.
|
|
87
|
-
*/
|
|
91
|
+
/** Duplicate releases never author another mutation. */
|
|
88
92
|
release() {
|
|
93
|
+
this.#dragOpen = false;
|
|
89
94
|
if (this.#state.phase === "pending")
|
|
90
95
|
return this.#state.operationId;
|
|
96
|
+
if (this.#state.phase !== "dragging")
|
|
97
|
+
return null;
|
|
98
|
+
const canonicalCells = this.#state.canonicalCells;
|
|
99
|
+
this.#emit({ phase: "idle", canonicalCells, outcome: null });
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
#submit() {
|
|
91
103
|
if (this.#state.phase !== "dragging")
|
|
92
104
|
return null;
|
|
93
105
|
const dragging = this.#state;
|
|
94
|
-
if (dragging.previewCells === dragging.canonicalCells)
|
|
95
|
-
this.#emit({ phase: "idle", canonicalCells: dragging.canonicalCells, outcome: null });
|
|
106
|
+
if (dragging.previewCells === dragging.canonicalCells)
|
|
96
107
|
return null;
|
|
97
|
-
|
|
108
|
+
this.#submittedCells = dragging.previewCells;
|
|
98
109
|
const operationId = nonEmpty(this.#options.operationId(), "operationId");
|
|
99
110
|
const submittedAt = this.#options.now();
|
|
100
111
|
if (!this.#projection)
|
|
@@ -146,10 +157,15 @@ export class ResizeTransactionController {
|
|
|
146
157
|
message: rejection.message,
|
|
147
158
|
});
|
|
148
159
|
}
|
|
149
|
-
/**
|
|
160
|
+
/** Discard queued motion; an already dispatched mutation cannot be undone. */
|
|
150
161
|
cancelDrag() {
|
|
151
|
-
if (this.#state.phase
|
|
162
|
+
if (!this.#dragOpen || this.#state.phase === "idle")
|
|
152
163
|
return false;
|
|
164
|
+
this.#dragOpen = false;
|
|
165
|
+
if (this.#state.phase === "pending") {
|
|
166
|
+
this.#emit({ ...this.#state, previewCells: this.#submittedCells });
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
153
169
|
const canonicalCells = this.#state.canonicalCells;
|
|
154
170
|
this.#emit({ phase: "idle", canonicalCells, outcome: null });
|
|
155
171
|
return true;
|
|
@@ -160,6 +176,8 @@ export class ResizeTransactionController {
|
|
|
160
176
|
}
|
|
161
177
|
/** Retire one runtime lane without permanently disposing the controller. */
|
|
162
178
|
retire() {
|
|
179
|
+
this.#dragOpen = false;
|
|
180
|
+
this.#submittedCells = null;
|
|
163
181
|
this.#clearTimeout();
|
|
164
182
|
this.#projection = null;
|
|
165
183
|
if (this.#state.phase !== "idle" || this.#state.canonicalCells !== null) {
|
|
@@ -172,7 +190,8 @@ export class ResizeTransactionController {
|
|
|
172
190
|
!this.#projection?.pending.some((operation) => operation.operationId === observation.operationId))
|
|
173
191
|
return false;
|
|
174
192
|
const cells = positiveCells(observation.cells, "observed cells");
|
|
175
|
-
const
|
|
193
|
+
const pending = this.#state;
|
|
194
|
+
const operationId = pending.operationId;
|
|
176
195
|
if (!this.#projection)
|
|
177
196
|
return false;
|
|
178
197
|
this.#revision += 1;
|
|
@@ -182,11 +201,19 @@ export class ResizeTransactionController {
|
|
|
182
201
|
value: cells,
|
|
183
202
|
}, { observedOperationIds: [operationId], nowMs: this.#options.now() });
|
|
184
203
|
this.#clearTimeout();
|
|
185
|
-
this.#
|
|
186
|
-
|
|
187
|
-
canonicalCells: cells
|
|
188
|
-
|
|
189
|
-
|
|
204
|
+
const hasLatest = pending.previewCells !== this.#submittedCells && pending.previewCells !== cells;
|
|
205
|
+
if (this.#dragOpen || hasLatest) {
|
|
206
|
+
this.#emit({ ...pending, phase: "dragging", canonicalCells: cells });
|
|
207
|
+
if (hasLatest)
|
|
208
|
+
this.#submit();
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.#emit({
|
|
212
|
+
phase: "idle",
|
|
213
|
+
canonicalCells: cells,
|
|
214
|
+
outcome: { kind: "settled", operationId, source, cells },
|
|
215
|
+
});
|
|
216
|
+
}
|
|
190
217
|
return true;
|
|
191
218
|
}
|
|
192
219
|
#revertTimedOut(operationId) {
|
|
@@ -202,6 +229,7 @@ export class ResizeTransactionController {
|
|
|
202
229
|
this.#projection = reconcileOptimisticOperation(this.#projection, operationId, reason.kind === "timed-out" ? "timed-out" : "rejected");
|
|
203
230
|
}
|
|
204
231
|
const canonicalCells = this.#state.canonicalCells;
|
|
232
|
+
this.#dragOpen = false;
|
|
205
233
|
this.#clearTimeout();
|
|
206
234
|
this.#emit({
|
|
207
235
|
phase: "idle",
|
|
@@ -1,14 +1,32 @@
|
|
|
1
|
+
import { createAutomaticContrastPass } from "../automatic-contrast.js";
|
|
1
2
|
import { VISUAL_THEME_PRESETS, findVisualThemePreset } from "@tmux-ide/contracts";
|
|
2
3
|
import { batch, createSignal } from "solid-js";
|
|
3
4
|
import { updateAppConfig } from "../../../lib/app-config.js";
|
|
4
5
|
import { createSemanticThemeStore, createTerminalPaletteProjection, deriveSystemVisualHostDefaults, } from "../theme.js";
|
|
5
6
|
import { createApplicationTransientNoteOwner } from "./application-transient-note-owner.js";
|
|
6
7
|
function hostDefaults(snapshot) {
|
|
7
|
-
|
|
8
|
-
return null;
|
|
9
|
-
return deriveSystemVisualHostDefaults(snapshot);
|
|
8
|
+
return (deriveSystemVisualHostDefaults(snapshot) ?? { appearance: snapshot.detectedMode, overrides: {} });
|
|
10
9
|
}
|
|
11
10
|
export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
11
|
+
const [automaticContrast, setAutomaticContrast] = createSignal(config.theme.automaticContrast ?? true);
|
|
12
|
+
const correct = createAutomaticContrastPass();
|
|
13
|
+
const postProcess = (buffer) => {
|
|
14
|
+
if (automaticContrast())
|
|
15
|
+
correct(buffer);
|
|
16
|
+
};
|
|
17
|
+
renderer.addPostProcessFn?.(postProcess);
|
|
18
|
+
const setContrast = (enabled) => {
|
|
19
|
+
if (enabled === automaticContrast())
|
|
20
|
+
return;
|
|
21
|
+
setAutomaticContrast(enabled);
|
|
22
|
+
renderer.requestRender?.();
|
|
23
|
+
};
|
|
24
|
+
const toggleAutomaticContrast = () => {
|
|
25
|
+
if (pickerOpen()) {
|
|
26
|
+
setContrast(!automaticContrast());
|
|
27
|
+
setPickerError(null);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
12
30
|
const initialHostPalette = terminalPaletteOwner.getSnapshot();
|
|
13
31
|
const store = createSemanticThemeStore(config.theme, {
|
|
14
32
|
rendererMode: renderer.themeMode,
|
|
@@ -65,10 +83,18 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
65
83
|
const apply = (id) => {
|
|
66
84
|
const preset = findVisualThemePreset(id);
|
|
67
85
|
const mode = preset?.appearance ?? id;
|
|
68
|
-
|
|
86
|
+
const wasSystem = theme().setting === "system";
|
|
87
|
+
store.configure({
|
|
88
|
+
...config.theme,
|
|
89
|
+
mode,
|
|
90
|
+
preset: preset?.id,
|
|
91
|
+
});
|
|
92
|
+
if (mode === "system" && !wasSystem)
|
|
93
|
+
void terminalPaletteOwner.refresh();
|
|
69
94
|
setPickerSelection(id);
|
|
70
95
|
};
|
|
71
96
|
let originalSelection = pickerSelection();
|
|
97
|
+
let originalContrast = automaticContrast();
|
|
72
98
|
const preview = (id) => {
|
|
73
99
|
if (!pickerOpen())
|
|
74
100
|
return;
|
|
@@ -79,6 +105,7 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
79
105
|
const cancelPicker = () => {
|
|
80
106
|
if (!pickerOpen())
|
|
81
107
|
return;
|
|
108
|
+
setContrast(originalContrast);
|
|
82
109
|
apply(originalSelection);
|
|
83
110
|
setPickerOpen(false);
|
|
84
111
|
setPickerError(null);
|
|
@@ -89,6 +116,7 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
89
116
|
try {
|
|
90
117
|
updateAppConfig({
|
|
91
118
|
theme: {
|
|
119
|
+
automaticContrast: automaticContrast(),
|
|
92
120
|
mode: theme().setting,
|
|
93
121
|
preset: findVisualThemePreset(pickerSelection())?.id ?? "",
|
|
94
122
|
},
|
|
@@ -105,7 +133,7 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
105
133
|
const order = ["dark", "light", "system"];
|
|
106
134
|
const next = order[(order.indexOf(theme().setting) + 1) % order.length];
|
|
107
135
|
apply(next);
|
|
108
|
-
updateAppConfig({ theme: { mode: next, preset: "" } });
|
|
136
|
+
updateAppConfig({ theme: { mode: next, preset: "", automaticContrast: automaticContrast() } });
|
|
109
137
|
notice.publish(`theme → ${next}`);
|
|
110
138
|
};
|
|
111
139
|
return {
|
|
@@ -116,6 +144,8 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
116
144
|
palette,
|
|
117
145
|
hostPalette,
|
|
118
146
|
setTransientNote: notice.publish,
|
|
147
|
+
automaticContrast,
|
|
148
|
+
toggleAutomaticContrast,
|
|
119
149
|
pickerOpen,
|
|
120
150
|
pickerError,
|
|
121
151
|
pickerQuery,
|
|
@@ -125,6 +155,7 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
125
155
|
if (pickerOpen())
|
|
126
156
|
return;
|
|
127
157
|
originalSelection = pickerSelection();
|
|
158
|
+
originalContrast = automaticContrast();
|
|
128
159
|
setPickerQuery("");
|
|
129
160
|
setPickerError(null);
|
|
130
161
|
setPickerOpen(true);
|
|
@@ -139,7 +170,9 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
139
170
|
return true;
|
|
140
171
|
const name = event.name.toLowerCase();
|
|
141
172
|
const choices = pickerOptions();
|
|
142
|
-
if (name === "
|
|
173
|
+
if (event.ctrl && name === "a")
|
|
174
|
+
toggleAutomaticContrast();
|
|
175
|
+
else if (name === "escape")
|
|
143
176
|
cancelPicker();
|
|
144
177
|
else if (name === "return" || name === "enter")
|
|
145
178
|
savePicker();
|
|
@@ -166,6 +199,7 @@ export function createAppearanceOwner(config, renderer, terminalPaletteOwner) {
|
|
|
166
199
|
},
|
|
167
200
|
cycleTheme,
|
|
168
201
|
dispose() {
|
|
202
|
+
renderer.removePostProcessFn?.(postProcess);
|
|
169
203
|
stopTheme();
|
|
170
204
|
stopRendererTheme();
|
|
171
205
|
stopHostPalette();
|
|
@@ -68,6 +68,7 @@ export function ApplicationMachineSidebar(props) {
|
|
|
68
68
|
}))
|
|
69
69
|
: []),
|
|
70
70
|
]));
|
|
71
|
+
const rowsByKey = createMemo(() => new Map(rows().map((row) => [row.key, row])));
|
|
71
72
|
const index = () => Math.max(0, rows().findIndex((row) => row.key === selectedKey()));
|
|
72
73
|
const controlGroup = () => {
|
|
73
74
|
const group = rows()[index()]?.group;
|
|
@@ -281,49 +282,69 @@ export function ApplicationMachineSidebar(props) {
|
|
|
281
282
|
revealFocusedRow();
|
|
282
283
|
};
|
|
283
284
|
}} height={machineHeight()} width={props.width} scrollX={false} scrollY={true} horizontalScrollbarOptions={{ visible: false }}>
|
|
284
|
-
<For each={rows()}>
|
|
285
|
-
{(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
285
|
+
<For each={rows().map((row) => row.key)}>
|
|
286
|
+
{(key) => {
|
|
287
|
+
// The semantic key owns the native row; fresh snapshots update its
|
|
288
|
+
// props instead of destroying and recreating identical renderables.
|
|
289
|
+
const current = createMemo((previous) => rowsByKey().get(key) ?? previous, rowsByKey().get(key));
|
|
290
|
+
const row = {
|
|
291
|
+
key,
|
|
292
|
+
get group() {
|
|
293
|
+
return current().group;
|
|
294
|
+
},
|
|
295
|
+
get session() {
|
|
296
|
+
return current().session;
|
|
297
|
+
},
|
|
298
|
+
get agent() {
|
|
299
|
+
return current().agent;
|
|
300
|
+
},
|
|
301
|
+
get agentHeading() {
|
|
302
|
+
return current().agentHeading;
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
return (<box width={Math.max(1, props.width - 1)} height={row.agent ? (row.agentHeading ? 3 : 2) : 1} flexShrink={0} flexDirection="column">
|
|
306
|
+
<Show when={row.agentHeading}>
|
|
307
|
+
<text height={1} fg={props.theme.roles.text.secondary}>
|
|
308
|
+
{" "}
|
|
309
|
+
Agents
|
|
310
|
+
</text>
|
|
311
|
+
</Show>
|
|
312
|
+
<NavigationRow theme={props.theme} id={`machine:${row.key}`} width={Math.max(1, props.width - 1)} labelColor={!row.agent && !row.session ? fleetHostColor(row.group) : undefined} label={row.agent
|
|
313
|
+
? row.agent.name
|
|
314
|
+
: row.session
|
|
315
|
+
? friendlySessionLabel(row.session.name)
|
|
316
|
+
: row.group.label} marker={row.agent
|
|
317
|
+
? active(row)
|
|
318
|
+
? row.agent.attention
|
|
319
|
+
? "›!"
|
|
320
|
+
: "›"
|
|
321
|
+
: row.agent.attention
|
|
322
|
+
? "!"
|
|
323
|
+
: "•"
|
|
324
|
+
: row.session
|
|
325
|
+
? props.model.favorites?.().includes(row.session.id)
|
|
326
|
+
? " ★"
|
|
327
|
+
: active(row)
|
|
328
|
+
? " ›"
|
|
329
|
+
: " "
|
|
330
|
+
: collapsed().has(preferenceKey(row.group))
|
|
331
|
+
? "▸"
|
|
332
|
+
: "▾"} detail={row.agent
|
|
333
|
+
? row.group.state !== "ready" || row.agent.disabled
|
|
318
334
|
? "unavailable"
|
|
319
|
-
:
|
|
320
|
-
: row.
|
|
321
|
-
?
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
335
|
+
: `[${terminalAgentStatusLabel(row.agent.activity)}]`
|
|
336
|
+
: row.session
|
|
337
|
+
? row.group.state !== "ready" || row.session.disabled
|
|
338
|
+
? "unavailable"
|
|
339
|
+
: `${row.session.paneCount}p${row.group.agents?.length ? ` ${activity(row).label}` : ""}`
|
|
340
|
+
: row.group.agents?.length && row.group.state === "ready"
|
|
341
|
+
? activity(row).label
|
|
342
|
+
: `${connectionDetail(row.group)}${row.group.agents?.length ? " ?" : ""}`} selected={Boolean((row.session || row.agent) && active(row))} focused={Boolean(focused() && row.key === selectedKey())} attention={row.agent?.attention ?? activity(row).kind === "attention"} onActivate={(source) => activate(row, source)}/>
|
|
343
|
+
<Show when={row.agent}>
|
|
344
|
+
{(agent) => (<text height={1} fg={props.theme.roles.text.muted} content={clipTerminal(` ${friendlySessionLabel(agent().sessionName)}`, Math.max(1, props.width - 1))}/>)}
|
|
345
|
+
</Show>
|
|
346
|
+
</box>);
|
|
347
|
+
}}
|
|
327
348
|
</For>
|
|
328
349
|
</scrollbox>
|
|
329
350
|
<For each={agentHeight() > 0 ? [true] : []}>
|