tmux-ide 2.9.0-beta.19 → 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 +1979 -783
- package/package.json +4 -2
- package/packages/contracts/src/__tests__/daemon-wire.test.ts +32 -0
- package/packages/contracts/src/daemon-events.ts +12 -12
- package/packages/contracts/src/daemon-wire.ts +30 -0
- package/packages/daemon/dist/command-center/agent-status-watch.js +9 -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/resources/fleet-preview-route.js +22 -6
- package/packages/daemon/dist/command-center/server.js +7 -0
- package/packages/daemon/dist/doctor.js +62 -0
- package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +400 -0
- package/packages/daemon/dist/lib/app-config.js +4 -2
- package/packages/daemon/dist/lib/canonical-daemon.js +1 -0
- package/packages/daemon/dist/lib/daemon-embed.js +24 -0
- package/packages/daemon/dist/lib/daemon-provenance.js +575 -0
- package/packages/daemon/dist/lib/headless-daemon.js +1 -0
- package/packages/daemon/dist/lib/log-sanitize.js +199 -0
- package/packages/daemon/dist/lib/log.js +123 -13
- package/packages/daemon/dist/lib/soak-diagnostics.js +124 -0
- package/packages/daemon/dist/lib/soak-verdict.js +472 -0
- package/packages/daemon/dist/lib/terminal-host-color.js +33 -0
- package/packages/daemon/dist/lib/tmux-external-interaction-observer.js +187 -39
- package/packages/daemon/dist/lib/tmux-interaction-retention.js +21 -0
- package/packages/daemon/dist/lib/workspace-promotion.js +55 -37
- package/packages/daemon/dist/terminal/mirror/session-channel.js +2 -1
- 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-fleet-preview.js +4 -1
- 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/dist/tui/team/wait-receipts.js +112 -33
- package/packages/daemon/src/command-center/agent-status-watch.ts +8 -2
- 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/resources/fleet-preview-route.ts +27 -5
- package/packages/daemon/src/command-center/server.ts +8 -0
- package/packages/daemon/src/doctor.ts +70 -0
- package/packages/daemon/src/lib/app-config.ts +11 -3
- package/packages/daemon/src/lib/canonical-daemon.ts +1 -0
- package/packages/daemon/src/lib/daemon-embed.ts +30 -0
- package/packages/daemon/src/lib/daemon-provenance.ts +769 -0
- package/packages/daemon/src/lib/fleet-preview-model.ts +1 -0
- package/packages/daemon/src/lib/headless-daemon.ts +1 -0
- package/packages/daemon/src/lib/log-sanitize.ts +248 -0
- package/packages/daemon/src/lib/log.ts +165 -14
- package/packages/daemon/src/lib/soak-diagnostics.ts +183 -0
- package/packages/daemon/src/lib/soak-verdict.ts +785 -0
- package/packages/daemon/src/lib/terminal-host-color.ts +43 -0
- package/packages/daemon/src/lib/tmux-external-interaction-observer.ts +233 -37
- package/packages/daemon/src/lib/tmux-interaction-retention.ts +24 -0
- package/packages/daemon/src/lib/workspace-promotion.ts +74 -45
- package/packages/daemon/src/terminal/mirror/session-channel.ts +2 -1
- 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-fleet-preview.ts +4 -0
- package/packages/daemon/src/tui/mirror/runtime/application-fleet-switcher.tsx +2 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +99 -75
- package/packages/daemon/src/tui/mirror/runtime/application-palette-preview.tsx +13 -3
- package/packages/daemon/src/tui/mirror/runtime/application-reference-sheet.tsx +125 -0
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +2 -1
- package/packages/daemon/src/tui/mirror/runtime/application-shell-overlays.tsx +199 -157
- 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/src/tui/team/wait-receipts.ts +115 -40
- package/packages/daemon-client/src/terminal-fast-lane.test.ts +18 -0
- package/packages/daemon-client/src/terminal-fast-lane.ts +7 -2
- package/packages/tmux-bridge/src/index.ts +2 -0
- package/packages/tmux-bridge/src/runner.test.ts +41 -0
- package/packages/tmux-bridge/src/runner.ts +41 -2
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/* @jsxImportSource @opentui/solid */
|
|
2
|
+
import { createSignal, For } from "solid-js";
|
|
3
|
+
import type { SemanticThemeSnapshot } from "../theme.ts";
|
|
4
|
+
import { Dialog } from "../ui/dialog.tsx";
|
|
5
|
+
import { TuiButton } from "../ui/button.tsx";
|
|
6
|
+
import { useKeyboardRoute } from "../ui/keyboard-router.tsx";
|
|
7
|
+
import { clipTerminal } from "../terminal-text.ts";
|
|
8
|
+
|
|
9
|
+
const shortcuts = [
|
|
10
|
+
"APPLICATION",
|
|
11
|
+
"F1 Home · F2 Terminals",
|
|
12
|
+
"F5 Commands · F6 Sessions across machines",
|
|
13
|
+
"F7 Agent attention · Ctrl+G Machine sidebar",
|
|
14
|
+
"IN THE COMMAND / SESSION MENU",
|
|
15
|
+
"Type to search · ↑/↓ choose · Enter activate",
|
|
16
|
+
"Ctrl+Space Toggle search / navigation mode",
|
|
17
|
+
"Navigation mode: j/k move · g/G first/last · i search",
|
|
18
|
+
"PageUp/PageDown page · Ctrl+U/D half page",
|
|
19
|
+
"Ctrl+H Local / all hosts · Ctrl+F Favorite session",
|
|
20
|
+
"Ctrl+←/→ Browse windows without activating them",
|
|
21
|
+
"Ctrl+P Show / hide preview · Ctrl+E Expand / restore",
|
|
22
|
+
"Ctrl+N New session · Ctrl+X Confirm close session",
|
|
23
|
+
"Ctrl+R Retry selected host",
|
|
24
|
+
"Ctrl+K Shortcuts · Ctrl+B What's new",
|
|
25
|
+
"Esc Close sheet / menu and return to your terminal",
|
|
26
|
+
];
|
|
27
|
+
const changes = [
|
|
28
|
+
"LATEST CHANGES",
|
|
29
|
+
"Agent previews follow the highlighted pane in the session.",
|
|
30
|
+
"Pane identity isolates cached previews and late responses.",
|
|
31
|
+
"Shortcuts and release history are available offline here.",
|
|
32
|
+
"",
|
|
33
|
+
"2.9.0-beta.18",
|
|
34
|
+
"Shared F5/F6 switcher with side-by-side previews in wide terminals.",
|
|
35
|
+
"Cached previews appear immediately while a fresh snapshot loads.",
|
|
36
|
+
"Fuzzy search, match highlighting, favorites and recent sessions.",
|
|
37
|
+
"Window browsing, expanded previews and bounded background work.",
|
|
38
|
+
"Create / confirm close on the selected host without leaving the menu.",
|
|
39
|
+
"",
|
|
40
|
+
"2.9.0-beta.17",
|
|
41
|
+
"Fleet navigation, passive window previews and activity summaries.",
|
|
42
|
+
"Adaptive refresh and exact-host actions across machines.",
|
|
43
|
+
"",
|
|
44
|
+
"Full release history: github.com/wavyrai/tmux-ide/releases",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
export function ApplicationReferenceSheet(props: {
|
|
48
|
+
page: "shortcuts" | "changes";
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
theme: SemanticThemeSnapshot;
|
|
52
|
+
onClose: () => void;
|
|
53
|
+
}) {
|
|
54
|
+
const [page, setPage] = createSignal(props.page);
|
|
55
|
+
const [offset, setOffset] = createSignal(0);
|
|
56
|
+
const rows = () => (page() === "shortcuts" ? shortcuts : changes);
|
|
57
|
+
const capacity = () => Math.max(1, Math.min(24, props.height - 8));
|
|
58
|
+
const move = (delta: number) =>
|
|
59
|
+
setOffset((v) => Math.max(0, Math.min(rows().length - capacity(), v + delta)));
|
|
60
|
+
const change = (next: "shortcuts" | "changes") => {
|
|
61
|
+
setPage(next);
|
|
62
|
+
setOffset(0);
|
|
63
|
+
};
|
|
64
|
+
useKeyboardRoute((event) => {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
event.stopPropagation();
|
|
67
|
+
if (event.eventType !== "press") return true;
|
|
68
|
+
const key = event.name.toLowerCase();
|
|
69
|
+
if (key === "escape") props.onClose();
|
|
70
|
+
else if (key === "tab") change(page() === "shortcuts" ? "changes" : "shortcuts");
|
|
71
|
+
else if (key === "down" || key === "j") move(1);
|
|
72
|
+
else if (key === "up" || key === "k") move(-1);
|
|
73
|
+
else if (key === "pagedown") move(capacity());
|
|
74
|
+
else if (key === "pageup") move(-capacity());
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
return (
|
|
78
|
+
<Dialog
|
|
79
|
+
theme={props.theme}
|
|
80
|
+
viewportWidth={props.width}
|
|
81
|
+
viewportHeight={props.height}
|
|
82
|
+
width={Math.min(88, Math.max(1, props.width - 4))}
|
|
83
|
+
height={Math.min(props.height, capacity() + 6)}
|
|
84
|
+
title={page() === "shortcuts" ? "Keyboard shortcuts" : "What's new"}
|
|
85
|
+
footer="Tab switch sheet · ↑↓ scroll · Esc back"
|
|
86
|
+
zIndex={100}
|
|
87
|
+
onDismiss={props.onClose}
|
|
88
|
+
>
|
|
89
|
+
<box height={1} flexDirection="row" gap={1}>
|
|
90
|
+
<TuiButton
|
|
91
|
+
theme={props.theme}
|
|
92
|
+
label="Shortcuts"
|
|
93
|
+
size="compact"
|
|
94
|
+
onPress={() => change("shortcuts")}
|
|
95
|
+
/>
|
|
96
|
+
<TuiButton
|
|
97
|
+
theme={props.theme}
|
|
98
|
+
label="What's new"
|
|
99
|
+
size="compact"
|
|
100
|
+
onPress={() => change("changes")}
|
|
101
|
+
/>
|
|
102
|
+
<TuiButton theme={props.theme} label="Back" size="compact" onPress={props.onClose} />
|
|
103
|
+
</box>
|
|
104
|
+
<box
|
|
105
|
+
flexDirection="column"
|
|
106
|
+
height={capacity()}
|
|
107
|
+
overflow="hidden"
|
|
108
|
+
onMouseScroll={(event) => {
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
move(event.scroll.direction === "up" ? -3 : 3);
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
<For each={rows().slice(offset(), offset() + capacity())}>
|
|
114
|
+
{(line) => (
|
|
115
|
+
<text
|
|
116
|
+
height={1}
|
|
117
|
+
fg={props.theme.roles.text.primary}
|
|
118
|
+
content={clipTerminal(line, Math.max(1, Math.min(88, props.width - 4) - 4))}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
</For>
|
|
122
|
+
</box>
|
|
123
|
+
</Dialog>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
@@ -441,7 +441,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
441
441
|
if (
|
|
442
442
|
(shell().semantic?.focus.palette.open || shell().localPaletteOpen) &&
|
|
443
443
|
event.ctrl &&
|
|
444
|
-
["left", "right", "p", "e", "n", "x", "f", "r"].includes(name) &&
|
|
444
|
+
["left", "right", "p", "e", "n", "x", "f", "r", "k", "b"].includes(name) &&
|
|
445
445
|
componentKeyboardRoutes.route(event)
|
|
446
446
|
)
|
|
447
447
|
return;
|
|
@@ -622,6 +622,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
622
622
|
})}
|
|
623
623
|
onResizePreview={recoverHostFocus(interaction.previewPaneResize)}
|
|
624
624
|
onResizePane={recoverHostFocus(interaction.resizePane)}
|
|
625
|
+
onCancelResize={interaction.cancelPaneResize}
|
|
625
626
|
onResizePointerIngress={recoverHostFocus.optional(resizeIngress)}
|
|
626
627
|
onWheelObservation={tuiPerfWheelObservation}
|
|
627
628
|
onTerminalInput={recoverHostFocus((paneId, input) =>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ApplicationReferenceSheet } from "./application-reference-sheet.tsx";
|
|
1
2
|
import { ApplicationFleetSessionActions } from "./application-fleet-session-actions.tsx";
|
|
2
3
|
import { ApplicationPalettePreview } from "./application-palette-preview.tsx";
|
|
3
4
|
/* @jsxImportSource @opentui/solid */
|
|
@@ -106,6 +107,12 @@ export function MinimalPalette(props: {
|
|
|
106
107
|
}): JSX.Element {
|
|
107
108
|
const [expanded, setExpanded] = createSignal(false);
|
|
108
109
|
const [modal, setModal] = createSignal(false);
|
|
110
|
+
const [sheet, setSheet] = createSignal<"shortcuts" | "changes">();
|
|
111
|
+
const openSheet = (page: "shortcuts" | "changes" | undefined) => {
|
|
112
|
+
setSheet(page);
|
|
113
|
+
setModal(!!page);
|
|
114
|
+
props.onModalChange?.(!!page);
|
|
115
|
+
};
|
|
109
116
|
const [lastHost, setLastHost] = createSignal<ApplicationPaletteCommand>();
|
|
110
117
|
createEffect(() => {
|
|
111
118
|
const c = props.commands[props.selected];
|
|
@@ -181,10 +188,11 @@ export function MinimalPalette(props: {
|
|
|
181
188
|
)
|
|
182
189
|
return false;
|
|
183
190
|
const key = event.name.toLowerCase();
|
|
184
|
-
if (!["f", "r"].includes(key)) return false;
|
|
191
|
+
if (!["f", "r", "k", "b"].includes(key)) return false;
|
|
185
192
|
event.preventDefault();
|
|
186
193
|
event.stopPropagation();
|
|
187
194
|
if (event.eventType !== "press") return true;
|
|
195
|
+
if (key === "k" || key === "b") openSheet(key === "k" ? "shortcuts" : "changes");
|
|
188
196
|
const c = selectedCommand();
|
|
189
197
|
if (c && key === "f") props.onFavorite?.(c);
|
|
190
198
|
if (typeof c === "object" && c.fleet && key === "r")
|
|
@@ -212,176 +220,203 @@ export function MinimalPalette(props: {
|
|
|
212
220
|
};
|
|
213
221
|
});
|
|
214
222
|
return (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
<text
|
|
230
|
-
height={1}
|
|
231
|
-
width={innerWidth()}
|
|
232
|
-
fg={props.theme.roles.text.link}
|
|
233
|
-
content={clipTerminal(
|
|
234
|
-
props.query
|
|
235
|
-
? `/ ${clipTerminalEnd(`${props.query}▏`, innerWidth() - 2)}`
|
|
236
|
-
: "/ Search commands…",
|
|
237
|
-
innerWidth(),
|
|
238
|
-
)}
|
|
239
|
-
/>
|
|
240
|
-
<Show when={height() >= 12}>
|
|
241
|
-
<box height={1} flexDirection="row" gap={1} overflow="hidden">
|
|
242
|
-
<Badge theme={props.theme} label={`${props.commands.length} matches`} />
|
|
243
|
-
<Show when={hasPreview()}>
|
|
244
|
-
<Badge theme={props.theme} label="PASSIVE PREVIEW" tone="neutral" />
|
|
245
|
-
</Show>
|
|
246
|
-
</box>
|
|
247
|
-
</Show>
|
|
248
|
-
<box
|
|
249
|
-
height={bodyHeight()}
|
|
250
|
-
flexDirection={sideBySide() ? "row" : "column"}
|
|
251
|
-
gap={sideBySide() ? 1 : 0}
|
|
252
|
-
overflow="hidden"
|
|
223
|
+
<>
|
|
224
|
+
<Dialog
|
|
225
|
+
theme={props.theme}
|
|
226
|
+
viewportWidth={props.width}
|
|
227
|
+
viewportHeight={props.height}
|
|
228
|
+
width={width()}
|
|
229
|
+
height={height()}
|
|
230
|
+
title={props.title ?? (innerWidth() >= 15 ? "Command palette" : "Commands")}
|
|
231
|
+
{...(height() >= 9
|
|
232
|
+
? { footer: props.keyboardHint ?? "↑↓ choose · Enter run · Esc close" }
|
|
233
|
+
: {})}
|
|
234
|
+
active={props.active !== false && !sheet()}
|
|
235
|
+
zIndex={props.zIndex}
|
|
236
|
+
onDismiss={props.onClose}
|
|
253
237
|
>
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
238
|
+
<text
|
|
239
|
+
height={1}
|
|
240
|
+
width={innerWidth()}
|
|
241
|
+
fg={props.theme.roles.text.link}
|
|
242
|
+
content={clipTerminal(
|
|
243
|
+
props.query
|
|
244
|
+
? `/ ${clipTerminalEnd(`${props.query}▏`, innerWidth() - 2)}`
|
|
245
|
+
: "/ Search commands…",
|
|
246
|
+
innerWidth(),
|
|
247
|
+
)}
|
|
248
|
+
/>
|
|
249
|
+
<Show when={height() >= 12}>
|
|
250
|
+
<box height={1} flexDirection="row" gap={1} overflow="hidden">
|
|
251
|
+
<TuiButton
|
|
252
|
+
theme={props.theme}
|
|
253
|
+
label="Shortcuts ^K"
|
|
254
|
+
size="compact"
|
|
255
|
+
onPress={() => openSheet("shortcuts")}
|
|
256
|
+
/>
|
|
257
|
+
<TuiButton
|
|
258
|
+
theme={props.theme}
|
|
259
|
+
label="What's new ^B"
|
|
260
|
+
size="compact"
|
|
261
|
+
onPress={() => openSheet("changes")}
|
|
262
|
+
/>
|
|
263
|
+
<Badge theme={props.theme} label={`${props.commands.length} matches`} />
|
|
264
|
+
<Show when={hasPreview()}>
|
|
265
|
+
<Badge theme={props.theme} label="PASSIVE PREVIEW" tone="neutral" />
|
|
266
|
+
</Show>
|
|
267
|
+
</box>
|
|
268
|
+
</Show>
|
|
269
|
+
<box
|
|
270
|
+
height={bodyHeight()}
|
|
271
|
+
flexDirection={sideBySide() ? "row" : "column"}
|
|
272
|
+
gap={sideBySide() ? 1 : 0}
|
|
273
|
+
overflow="hidden"
|
|
274
|
+
>
|
|
275
|
+
<Show when={!expanded()}>
|
|
276
|
+
<box
|
|
277
|
+
width={listWidth()}
|
|
278
|
+
height={visibleCapacity()}
|
|
279
|
+
flexDirection="column"
|
|
280
|
+
overflow="hidden"
|
|
281
|
+
onMouseScroll={(event) => {
|
|
282
|
+
if (props.active === false || !props.commands.length) return;
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
event.stopPropagation();
|
|
285
|
+
props.onSelect?.(
|
|
286
|
+
Math.max(
|
|
287
|
+
0,
|
|
288
|
+
Math.min(
|
|
289
|
+
props.commands.length - 1,
|
|
290
|
+
props.selected + (event.scroll?.direction === "up" ? -1 : 1),
|
|
291
|
+
),
|
|
270
292
|
),
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
}}
|
|
274
|
-
>
|
|
275
|
-
<Show
|
|
276
|
-
when={props.commands.length > 0}
|
|
277
|
-
fallback={
|
|
278
|
-
<text
|
|
279
|
-
height={1}
|
|
280
|
-
width={innerWidth()}
|
|
281
|
-
fg={props.theme.roles.text.muted}
|
|
282
|
-
content={clipTerminal("No matches · Ctrl+U clear", innerWidth())}
|
|
283
|
-
/>
|
|
284
|
-
}
|
|
293
|
+
);
|
|
294
|
+
}}
|
|
285
295
|
>
|
|
286
|
-
<
|
|
287
|
-
{
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
props.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
296
|
+
<Show
|
|
297
|
+
when={props.commands.length > 0}
|
|
298
|
+
fallback={
|
|
299
|
+
<text
|
|
300
|
+
height={1}
|
|
301
|
+
width={innerWidth()}
|
|
302
|
+
fg={props.theme.roles.text.muted}
|
|
303
|
+
content={clipTerminal("No matches · Ctrl+U clear", innerWidth())}
|
|
304
|
+
/>
|
|
305
|
+
}
|
|
306
|
+
>
|
|
307
|
+
<For
|
|
308
|
+
each={commandRows().map((row) => applicationCommandDescription(row.command).id)}
|
|
309
|
+
>
|
|
310
|
+
{(id) => {
|
|
311
|
+
const row = () =>
|
|
312
|
+
commandRows().find(
|
|
313
|
+
(row) => applicationCommandDescription(row.command).id === id,
|
|
314
|
+
)!;
|
|
315
|
+
return (
|
|
316
|
+
<OverlayListRow
|
|
317
|
+
theme={props.theme}
|
|
318
|
+
id={id}
|
|
319
|
+
label={`${typeof row().command === "object" && (row().command as { fleet?: { favorite?: boolean } }).fleet?.favorite ? "★ " : ""}${commandLabel(row().command)}`}
|
|
320
|
+
query={props.query}
|
|
321
|
+
width={listWidth()}
|
|
322
|
+
selected={props.selected === row().index}
|
|
323
|
+
reserveMarker={innerWidth() >= 16}
|
|
324
|
+
disabled={
|
|
325
|
+
props.active === false || Boolean(props.disabledReason?.(row().command))
|
|
326
|
+
}
|
|
327
|
+
danger={props.closeArmed && row().command === "close-pane"}
|
|
328
|
+
onHighlight={() => props.onSelect?.(row().index)}
|
|
329
|
+
onPress={() => {
|
|
330
|
+
props.onSelect?.(row().index);
|
|
331
|
+
props.onActivate(row().command);
|
|
332
|
+
}}
|
|
333
|
+
/>
|
|
334
|
+
);
|
|
335
|
+
}}
|
|
336
|
+
</For>
|
|
337
|
+
</Show>
|
|
338
|
+
</box>
|
|
339
|
+
</Show>
|
|
340
|
+
<Show when={sideBySide()}>
|
|
341
|
+
<text
|
|
342
|
+
width={1}
|
|
343
|
+
height={bodyHeight()}
|
|
344
|
+
fg={props.theme.roles.text.muted}
|
|
345
|
+
content={Array(bodyHeight()).fill("│").join("\n")}
|
|
346
|
+
/>
|
|
347
|
+
</Show>
|
|
348
|
+
<Show when={hasPreview()}>
|
|
349
|
+
<ApplicationPalettePreview
|
|
350
|
+
command={selectedCommand()}
|
|
351
|
+
width={previewWidth()}
|
|
352
|
+
height={previewHeight()}
|
|
353
|
+
theme={props.theme}
|
|
354
|
+
active={!modal() && props.active !== false && props.previewActive !== false}
|
|
355
|
+
onExpandedChange={setExpanded}
|
|
356
|
+
/>
|
|
357
|
+
</Show>
|
|
358
|
+
</box>
|
|
359
|
+
<Show when={hasPreview()}>
|
|
360
|
+
<box height={2} flexDirection="row" gap={1} overflow="hidden">
|
|
361
|
+
<ApplicationFleetSessionActions
|
|
362
|
+
command={selectedCommand()}
|
|
363
|
+
width={props.width}
|
|
364
|
+
height={props.height}
|
|
365
|
+
theme={props.theme}
|
|
366
|
+
initialName={props.commands.length === 0 ? props.query : undefined}
|
|
367
|
+
active={props.active !== false && props.previewActive !== false}
|
|
368
|
+
onModalChange={(open) => {
|
|
369
|
+
setModal(open);
|
|
370
|
+
props.onModalChange?.(open);
|
|
371
|
+
}}
|
|
372
|
+
/>
|
|
373
|
+
<Show when={favorite() !== undefined && props.onFavorite}>
|
|
374
|
+
<KeyHint
|
|
375
|
+
theme={props.theme}
|
|
376
|
+
keys="^F"
|
|
377
|
+
label={favorite() ? "Unfavorite" : "Favorite"}
|
|
378
|
+
disabled={props.active === false || props.previewActive === false}
|
|
379
|
+
onPress={() => {
|
|
380
|
+
const c = selectedCommand();
|
|
381
|
+
if (c) props.onFavorite?.(c);
|
|
312
382
|
}}
|
|
313
|
-
|
|
383
|
+
/>
|
|
314
384
|
</Show>
|
|
315
385
|
</box>
|
|
316
386
|
</Show>
|
|
317
|
-
<Show when={
|
|
387
|
+
<Show when={height() >= 9}>
|
|
318
388
|
<text
|
|
319
|
-
|
|
320
|
-
|
|
389
|
+
height={1}
|
|
390
|
+
width={innerWidth()}
|
|
321
391
|
fg={props.theme.roles.text.muted}
|
|
322
|
-
content={
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
392
|
+
content={clipTerminal(
|
|
393
|
+
(() => {
|
|
394
|
+
const command = props.commands[props.selected];
|
|
395
|
+
if (!command) return "Try an action, agent or session name";
|
|
396
|
+
return (
|
|
397
|
+
props.disabledReason?.(command) ??
|
|
398
|
+
(props.closeArmed
|
|
399
|
+
? "Closes the pane and its running process"
|
|
400
|
+
: `${props.selected + 1}/${props.commands.length} · ${applicationCommandDescription(command).detail}`)
|
|
401
|
+
);
|
|
402
|
+
})(),
|
|
403
|
+
innerWidth(),
|
|
404
|
+
)}
|
|
333
405
|
/>
|
|
334
406
|
</Show>
|
|
335
|
-
</
|
|
336
|
-
<Show when={
|
|
337
|
-
|
|
338
|
-
<
|
|
339
|
-
|
|
407
|
+
</Dialog>
|
|
408
|
+
<Show when={sheet()}>
|
|
409
|
+
{(page) => (
|
|
410
|
+
<ApplicationReferenceSheet
|
|
411
|
+
page={page()}
|
|
340
412
|
width={props.width}
|
|
341
413
|
height={props.height}
|
|
342
414
|
theme={props.theme}
|
|
343
|
-
|
|
344
|
-
active={props.active !== false && props.previewActive !== false}
|
|
345
|
-
onModalChange={(open) => {
|
|
346
|
-
setModal(open);
|
|
347
|
-
props.onModalChange?.(open);
|
|
348
|
-
}}
|
|
415
|
+
onClose={() => openSheet(undefined)}
|
|
349
416
|
/>
|
|
350
|
-
|
|
351
|
-
<KeyHint
|
|
352
|
-
theme={props.theme}
|
|
353
|
-
keys="^F"
|
|
354
|
-
label={favorite() ? "Unfavorite" : "Favorite"}
|
|
355
|
-
disabled={props.active === false || props.previewActive === false}
|
|
356
|
-
onPress={() => {
|
|
357
|
-
const c = selectedCommand();
|
|
358
|
-
if (c) props.onFavorite?.(c);
|
|
359
|
-
}}
|
|
360
|
-
/>
|
|
361
|
-
</Show>
|
|
362
|
-
</box>
|
|
363
|
-
</Show>
|
|
364
|
-
<Show when={height() >= 9}>
|
|
365
|
-
<text
|
|
366
|
-
height={1}
|
|
367
|
-
width={innerWidth()}
|
|
368
|
-
fg={props.theme.roles.text.muted}
|
|
369
|
-
content={clipTerminal(
|
|
370
|
-
(() => {
|
|
371
|
-
const command = props.commands[props.selected];
|
|
372
|
-
if (!command) return "Try an action, agent or session name";
|
|
373
|
-
return (
|
|
374
|
-
props.disabledReason?.(command) ??
|
|
375
|
-
(props.closeArmed
|
|
376
|
-
? "Closes the pane and its running process"
|
|
377
|
-
: `${props.selected + 1}/${props.commands.length} · ${applicationCommandDescription(command).detail}`)
|
|
378
|
-
);
|
|
379
|
-
})(),
|
|
380
|
-
innerWidth(),
|
|
381
|
-
)}
|
|
382
|
-
/>
|
|
417
|
+
)}
|
|
383
418
|
</Show>
|
|
384
|
-
|
|
419
|
+
</>
|
|
385
420
|
);
|
|
386
421
|
}
|
|
387
422
|
|
|
@@ -458,7 +493,7 @@ export function AppearanceDialog(props: {
|
|
|
458
493
|
viewportWidth={props.width}
|
|
459
494
|
viewportHeight={props.height}
|
|
460
495
|
width={width()}
|
|
461
|
-
height={Math.min(
|
|
496
|
+
height={Math.min(19, props.height)}
|
|
462
497
|
title="Appearance"
|
|
463
498
|
footer={width() < 40 ? "Enter save · Esc back" : "↑↓ preview · Enter save · Esc cancel"}
|
|
464
499
|
active={props.active}
|
|
@@ -470,10 +505,17 @@ export function AppearanceDialog(props: {
|
|
|
470
505
|
fg={props.owner.theme().roles.text.primary}
|
|
471
506
|
content={`Search: ${props.owner.pickerQuery() || "type to filter"}`}
|
|
472
507
|
/>
|
|
508
|
+
<TuiButton
|
|
509
|
+
theme={props.owner.theme()}
|
|
510
|
+
label={`^A Contrast: ${props.owner.automaticContrast() ? "On" : "Off"}`}
|
|
511
|
+
size="compact"
|
|
512
|
+
disabled={props.active === false}
|
|
513
|
+
onPress={props.owner.toggleAutomaticContrast}
|
|
514
|
+
/>
|
|
473
515
|
<For
|
|
474
516
|
each={(() => {
|
|
475
517
|
const options = props.owner.pickerOptions();
|
|
476
|
-
const count = Math.max(1, Math.min(10, props.height -
|
|
518
|
+
const count = Math.max(1, Math.min(10, props.height - 9));
|
|
477
519
|
const index = options.findIndex((p) => p.id === props.owner.pickerSelection());
|
|
478
520
|
const start = Math.max(
|
|
479
521
|
0,
|
|
@@ -125,6 +125,7 @@ export interface ApplicationShellViewProps {
|
|
|
125
125
|
readonly onSelectPane: TerminalWorkspaceProps["onSelectPane"];
|
|
126
126
|
readonly onResizePreview: TerminalWorkspaceProps["onResizePreview"];
|
|
127
127
|
readonly onResizePane: TerminalWorkspaceProps["onResizePane"];
|
|
128
|
+
readonly onCancelResize?: TerminalWorkspaceProps["onCancelResize"];
|
|
128
129
|
readonly onResizePointerIngress?: TerminalWorkspaceProps["onResizePointerIngress"];
|
|
129
130
|
readonly onWheelObservation?: TerminalWorkspaceProps["onWheelObservation"];
|
|
130
131
|
readonly onTerminalInput?: TerminalWorkspaceProps["onTerminalInput"];
|
|
@@ -517,6 +518,7 @@ export function ApplicationShellView(props: ApplicationShellViewProps): JSX.Elem
|
|
|
517
518
|
}}
|
|
518
519
|
onResizePreview={props.onResizePreview}
|
|
519
520
|
onResizePane={props.onResizePane}
|
|
521
|
+
onCancelResize={props.onCancelResize}
|
|
520
522
|
onResizePointerIngress={props.onResizePointerIngress}
|
|
521
523
|
onWheelObservation={props.onWheelObservation}
|
|
522
524
|
onTerminalInput={props.onTerminalInput}
|