tmux-ide 2.9.0-beta.21 → 2.9.0-beta.26
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 +46791 -43589
- package/package.json +2 -2
- package/packages/contracts/src/__tests__/daemon-wire.test.ts +2 -2
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v3.json +35 -0
- package/packages/contracts/src/__tests__/issue-error.test.ts +1 -1
- package/packages/contracts/src/__tests__/multiplexer-verbs.test.ts +3 -1
- package/packages/contracts/src/__tests__/pane-stream.test.ts +17 -5
- package/packages/contracts/src/__tests__/tmux-server-scope.test.ts +166 -0
- package/packages/contracts/src/__tests__/window-links.test.ts +243 -0
- package/packages/contracts/src/actions-contract.ts +12 -0
- package/packages/contracts/src/daemon-resource-request.test.ts +1 -1
- package/packages/contracts/src/daemon-wire.ts +10 -5
- package/packages/contracts/src/fleet-client-state.ts +3 -0
- package/packages/contracts/src/fleet-lifecycle.ts +5 -0
- package/packages/contracts/src/index.ts +2 -0
- package/packages/contracts/src/interaction-receipts.ts +39 -0
- package/packages/contracts/src/issue-error.ts +1 -1
- package/packages/contracts/src/multiplexer-verbs.ts +25 -1
- package/packages/contracts/src/pane-stream.ts +51 -8
- package/packages/contracts/src/tmux-server-scope.ts +172 -0
- package/packages/contracts/src/window-links.ts +76 -0
- package/packages/contracts/src/workspace-multiplexer.ts +54 -0
- package/packages/core/src/interaction-receipts.ts +4 -0
- package/packages/daemon/dist/command-center/actions/command-definitions.js +6 -0
- package/packages/daemon/dist/command-center/actions/handlers/workspace-multiplexer.js +2 -0
- package/packages/daemon/dist/command-center/actions/registry.js +13 -1
- package/packages/daemon/dist/command-center/discovery.js +2 -9
- package/packages/daemon/dist/command-center/server.js +21 -1
- package/packages/daemon/dist/command-center/tmux-server-native-backing.js +37 -0
- package/packages/daemon/dist/command-center/tmux-servers.js +351 -0
- package/packages/daemon/dist/lib/canonical-daemon-bootstrap.js +64 -8
- package/packages/daemon/dist/lib/canonical-daemon.js +5 -2
- package/packages/daemon/dist/lib/daemon-embed.js +198 -30
- package/packages/daemon/dist/lib/embedded-tmux-server-owners.js +147 -0
- package/packages/daemon/dist/lib/fleet-lifecycle-authority.js +31 -11
- package/packages/daemon/dist/lib/headless-daemon.js +10 -1
- package/packages/daemon/dist/lib/runtime-namespace.js +17 -3
- package/packages/daemon/dist/lib/tmux-client-execution.js +59 -0
- package/packages/daemon/dist/lib/tmux-named-socket-fence.js +4 -0
- package/packages/daemon/dist/lib/tmux-server-generation-runner.js +62 -0
- package/packages/daemon/dist/lib/tmux-server-owner.js +285 -0
- package/packages/daemon/dist/lib/tmux-server-owners.js +192 -0
- package/packages/daemon/dist/lib/tmux-server-proof.js +82 -0
- package/packages/daemon/dist/lib/tmux-server-registration.js +85 -0
- package/packages/daemon/dist/lib/tmux-server-session-create.js +43 -0
- package/packages/daemon/dist/lib/tmux-server-session-open.js +101 -0
- package/packages/daemon/dist/lib/tmux-servers-cli.js +134 -0
- package/packages/daemon/dist/lib/tmux-session-mutation-fence.js +55 -0
- package/packages/daemon/dist/lib/tmux-window-link-guard.js +88 -0
- package/packages/daemon/dist/lib/workspace-config-loader.js +3 -0
- package/packages/daemon/dist/lib/workspace-multiplexer-verbs.js +82 -1
- package/packages/daemon/dist/lib/workspace-pane-creation.js +13 -57
- package/packages/daemon/dist/lib/workspace-promotion.js +91 -12
- package/packages/daemon/dist/lib/workspace-registry.js +4 -0
- package/packages/daemon/dist/server/pane-stream-upgrade.js +20 -6
- package/packages/daemon/dist/terminal/attachments/native-runtime.js +61 -17
- package/packages/daemon/dist/terminal/mirror/__tests__/scripted-channel.js +9 -1
- package/packages/daemon/dist/terminal/mirror/__tests__/simulated-channel.js +11 -2
- package/packages/daemon/dist/terminal/mirror/control-channel.js +65 -6
- package/packages/daemon/dist/terminal/mirror/mirror-service.js +44 -0
- package/packages/daemon/dist/terminal/mirror/session-channel.js +210 -50
- package/packages/daemon/dist/terminal/mirror/window-link-authority.js +160 -0
- package/packages/daemon/dist/terminal/pane-stream/lease-manager.js +3 -3
- package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +40 -6
- package/packages/daemon/dist/terminal/protocol/live-session-identity.js +9 -0
- package/packages/daemon/dist/terminal/protocol/native-backing-client.js +2 -1
- package/packages/daemon/dist/terminal/session-runtime/interaction-receipt-facts.js +9 -0
- package/packages/daemon/dist/terminal/session-runtime/registry.js +6 -0
- package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-executor.js +1 -1
- package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-resource-changes.js +1 -0
- package/packages/daemon/dist/tui/mirror/application-shell-daemon-connection.js +7 -2
- package/packages/daemon/dist/tui/mirror/application-shell-server-connection.js +114 -0
- package/packages/daemon/dist/tui/mirror/menu-model.js +1 -1
- package/packages/daemon/dist/tui/mirror/open-tui-verified-routing.js +34 -4
- package/packages/daemon/dist/tui/mirror/open-tui-workspace-runtime-port.js +29 -8
- package/packages/daemon/dist/tui/mirror/runtime/application-guided-tour-integration.jsx +119 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-guided-tour-owner.js +132 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-home-agent-roster.jsx +21 -9
- package/packages/daemon/dist/tui/mirror/runtime/application-home-agent-transport.js +63 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-home-agents-owner.js +8 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-home-agents.js +3 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-home-catalog-owner.js +11 -5
- package/packages/daemon/dist/tui/mirror/runtime/application-home-catalog.js +140 -75
- package/packages/daemon/dist/tui/mirror/runtime/application-home-experience.js +40 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-home-fleet.js +132 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-agents.js +9 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-catalog.js +12 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +211 -31
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +91 -37
- package/packages/daemon/dist/tui/mirror/runtime/application-performance-log.js +20 -7
- package/packages/daemon/dist/tui/mirror/runtime/application-root-configuration.js +9 -3
- package/packages/daemon/dist/tui/mirror/runtime/application-route-connection.js +95 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-shell-home.jsx +6 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +158 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace-policy.js +43 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace.jsx +78 -25
- package/packages/daemon/dist/tui/mirror/runtime/application-theme-repaint.js +9 -0
- package/packages/daemon/dist/tui/mirror/runtime/fleet-lifecycle-client.js +44 -1
- package/packages/daemon/dist/tui/mirror/runtime/guided-tour-coach.jsx +54 -0
- package/packages/daemon/dist/tui/mirror/runtime/guided-tour-storage.js +67 -0
- package/packages/daemon/dist/tui/mirror/runtime/guided-tour.js +113 -0
- package/packages/daemon/dist/tui/mirror/runtime/open-tui-generation-host.js +1 -1
- package/packages/daemon/dist/tui/mirror/runtime/resize-terminal-pane.js +4 -0
- package/packages/daemon/dist/tui/mirror/runtime/select-terminal-pane.js +2 -1
- package/packages/daemon/dist/tui/mirror/runtime/semantic-shell-viewport-resize.js +12 -4
- package/packages/daemon/dist/tui/mirror/runtime/terminal-pane-input-router.js +6 -3
- package/packages/daemon/dist/tui/mirror/workspace/application-command-description.js +11 -2
- package/packages/daemon/dist/tui/mirror/workspace/terminal-window-strip.jsx +2 -1
- package/packages/daemon/src/command-center/actions/command-definitions.ts +6 -0
- package/packages/daemon/src/command-center/actions/errors.ts +4 -0
- package/packages/daemon/src/command-center/actions/handlers/workspace-multiplexer.ts +2 -0
- package/packages/daemon/src/command-center/actions/registry.ts +14 -0
- package/packages/daemon/src/command-center/discovery.ts +2 -10
- package/packages/daemon/src/command-center/server.ts +29 -1
- package/packages/daemon/src/command-center/tmux-server-native-backing.ts +49 -0
- package/packages/daemon/src/command-center/tmux-servers.ts +479 -0
- package/packages/daemon/src/lib/canonical-daemon-bootstrap.ts +111 -4
- package/packages/daemon/src/lib/canonical-daemon.ts +15 -3
- package/packages/daemon/src/lib/daemon-embed.ts +241 -28
- package/packages/daemon/src/lib/embedded-tmux-server-owners.ts +190 -0
- package/packages/daemon/src/lib/fleet-lifecycle-authority.ts +33 -9
- package/packages/daemon/src/lib/headless-daemon.ts +18 -1
- package/packages/daemon/src/lib/runtime-namespace.ts +24 -3
- package/packages/daemon/src/lib/tmux-client-execution.ts +56 -0
- package/packages/daemon/src/lib/tmux-named-socket-fence.ts +5 -0
- package/packages/daemon/src/lib/tmux-server-generation-runner.ts +81 -0
- package/packages/daemon/src/lib/tmux-server-owner.ts +336 -0
- package/packages/daemon/src/lib/tmux-server-owners.ts +228 -0
- package/packages/daemon/src/lib/tmux-server-proof.ts +95 -0
- package/packages/daemon/src/lib/tmux-server-registration.ts +105 -0
- package/packages/daemon/src/lib/tmux-server-session-create.ts +52 -0
- package/packages/daemon/src/lib/tmux-server-session-open.ts +106 -0
- package/packages/daemon/src/lib/tmux-servers-cli.ts +186 -0
- package/packages/daemon/src/lib/tmux-session-mutation-fence.ts +62 -0
- package/packages/daemon/src/lib/tmux-window-link-guard.ts +112 -0
- package/packages/daemon/src/lib/workspace-config-loader.ts +3 -0
- package/packages/daemon/src/lib/workspace-multiplexer-verbs.ts +121 -1
- package/packages/daemon/src/lib/workspace-pane-creation.ts +16 -55
- package/packages/daemon/src/lib/workspace-promotion.ts +98 -12
- package/packages/daemon/src/lib/workspace-registry.ts +5 -0
- package/packages/daemon/src/server/pane-stream-upgrade.ts +25 -5
- package/packages/daemon/src/terminal/attachments/native-runtime.ts +70 -16
- package/packages/daemon/src/terminal/mirror/control-channel.ts +64 -7
- package/packages/daemon/src/terminal/mirror/events.ts +2 -0
- package/packages/daemon/src/terminal/mirror/mirror-service.ts +56 -0
- package/packages/daemon/src/terminal/mirror/session-channel.ts +245 -50
- package/packages/daemon/src/terminal/mirror/window-link-authority.ts +203 -0
- package/packages/daemon/src/terminal/pane-stream/lease-manager.ts +3 -3
- package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +50 -6
- package/packages/daemon/src/terminal/protocol/live-session-identity.ts +14 -0
- package/packages/daemon/src/terminal/protocol/native-backing-client.ts +4 -1
- package/packages/daemon/src/terminal/session-runtime/interaction-receipt-facts.ts +9 -0
- package/packages/daemon/src/terminal/session-runtime/registry.ts +9 -0
- package/packages/daemon/src/terminal/session-runtime/semantic-mutation-executor.ts +2 -2
- package/packages/daemon/src/terminal/session-runtime/semantic-mutation-resource-changes.ts +1 -0
- package/packages/daemon/src/tui/mirror/application-shell-daemon-connection.ts +28 -2
- package/packages/daemon/src/tui/mirror/application-shell-server-connection.ts +154 -0
- package/packages/daemon/src/tui/mirror/menu-model.ts +1 -1
- package/packages/daemon/src/tui/mirror/open-tui-verified-routing.ts +41 -3
- package/packages/daemon/src/tui/mirror/open-tui-workspace-runtime-port.ts +47 -6
- package/packages/daemon/src/tui/mirror/runtime/application-entry.ts +2 -1
- package/packages/daemon/src/tui/mirror/runtime/application-fleet-session-actions.tsx +10 -4
- package/packages/daemon/src/tui/mirror/runtime/application-fleet-tabs.ts +2 -0
- package/packages/daemon/src/tui/mirror/runtime/application-guided-tour-integration.tsx +199 -0
- package/packages/daemon/src/tui/mirror/runtime/application-guided-tour-owner.ts +162 -0
- package/packages/daemon/src/tui/mirror/runtime/application-home-agent-roster.tsx +36 -10
- package/packages/daemon/src/tui/mirror/runtime/application-home-agent-transport.ts +69 -0
- package/packages/daemon/src/tui/mirror/runtime/application-home-agents-owner.ts +12 -2
- package/packages/daemon/src/tui/mirror/runtime/application-home-agents.ts +13 -2
- package/packages/daemon/src/tui/mirror/runtime/application-home-catalog-owner.ts +13 -3
- package/packages/daemon/src/tui/mirror/runtime/application-home-catalog.ts +172 -100
- package/packages/daemon/src/tui/mirror/runtime/application-home-experience.ts +59 -0
- package/packages/daemon/src/tui/mirror/runtime/application-home-fleet.ts +175 -0
- package/packages/daemon/src/tui/mirror/runtime/application-machine-agents.ts +9 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-catalog.ts +19 -7
- package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +285 -36
- package/packages/daemon/src/tui/mirror/runtime/application-machine-overlays.tsx +1 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +124 -40
- package/packages/daemon/src/tui/mirror/runtime/application-palette-preview.tsx +3 -0
- package/packages/daemon/src/tui/mirror/runtime/application-performance-log.ts +18 -6
- package/packages/daemon/src/tui/mirror/runtime/application-root-configuration.ts +12 -3
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +40 -40
- package/packages/daemon/src/tui/mirror/runtime/application-route-connection.ts +93 -1
- package/packages/daemon/src/tui/mirror/runtime/application-shell-catalog.tsx +4 -0
- package/packages/daemon/src/tui/mirror/runtime/application-shell-home.tsx +20 -1
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +10 -0
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +177 -2
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace-policy.ts +62 -0
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace.tsx +87 -30
- package/packages/daemon/src/tui/mirror/runtime/application-theme-repaint.ts +19 -0
- package/packages/daemon/src/tui/mirror/runtime/fleet-lifecycle-client.ts +55 -0
- package/packages/daemon/src/tui/mirror/runtime/guided-tour-coach.tsx +118 -0
- package/packages/daemon/src/tui/mirror/runtime/guided-tour-storage.ts +72 -0
- package/packages/daemon/src/tui/mirror/runtime/guided-tour.ts +147 -0
- package/packages/daemon/src/tui/mirror/runtime/open-tui-generation-host.ts +1 -1
- package/packages/daemon/src/tui/mirror/runtime/resize-terminal-pane.ts +3 -0
- package/packages/daemon/src/tui/mirror/runtime/select-terminal-pane.ts +3 -0
- package/packages/daemon/src/tui/mirror/runtime/semantic-shell-viewport-resize.ts +11 -4
- package/packages/daemon/src/tui/mirror/runtime/terminal-pane-input-router.ts +15 -4
- package/packages/daemon/src/tui/mirror/workspace/application-command-description.ts +13 -2
- package/packages/daemon/src/tui/mirror/workspace/terminal-window-strip.tsx +5 -1
- package/packages/daemon-client/package.json +3 -1
- package/packages/daemon-client/src/index.ts +2 -0
- package/packages/daemon-client/src/pane-stream-client.test.ts +108 -38
- package/packages/daemon-client/src/pane-stream-client.ts +26 -0
- package/packages/daemon-client/src/scoped-tmux-server-transport.test.ts +114 -0
- package/packages/daemon-client/src/scoped-tmux-server-transport.ts +385 -0
- package/packages/daemon-client/src/tmux-server-client.test.ts +279 -0
- package/packages/daemon-client/src/tmux-server-client.ts +287 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TmuxServerDescriptor, TmuxServerScope } from "@tmux-ide/contracts";
|
|
1
2
|
import { fleetHostColor, summarizeFleetActivity } from "./fleet-presentation.ts";
|
|
2
3
|
import { TuiButton } from "../ui/button.tsx";
|
|
3
4
|
/* @jsxImportSource @opentui/solid */
|
|
@@ -24,6 +25,7 @@ import { Surface } from "../ui/surface.tsx";
|
|
|
24
25
|
import { useKeyboardRoute } from "../ui/keyboard-router.tsx";
|
|
25
26
|
|
|
26
27
|
export interface ApplicationMachineAgent {
|
|
28
|
+
readonly server?: TmuxServerScope;
|
|
27
29
|
readonly id: string;
|
|
28
30
|
readonly name: string;
|
|
29
31
|
readonly sessionName: string;
|
|
@@ -41,8 +43,11 @@ export interface ApplicationMachineGroup {
|
|
|
41
43
|
readonly id: string;
|
|
42
44
|
readonly label: string;
|
|
43
45
|
readonly state: "ready" | "connecting" | "disconnected";
|
|
46
|
+
readonly servers?: readonly TmuxServerDescriptor[];
|
|
44
47
|
readonly sessions: readonly {
|
|
45
48
|
readonly id: string;
|
|
49
|
+
readonly server?: TmuxServerScope;
|
|
50
|
+
readonly serverLabel?: string;
|
|
46
51
|
readonly name: string;
|
|
47
52
|
readonly paneCount: number;
|
|
48
53
|
readonly disabled?: boolean;
|
|
@@ -56,8 +61,15 @@ export interface ApplicationMachineSidebarModel {
|
|
|
56
61
|
readonly onCollapse?: (key: string, enabled: boolean) => void;
|
|
57
62
|
readonly activeMachineId: Accessor<string | null>;
|
|
58
63
|
readonly activeSessionName: Accessor<string | null>;
|
|
64
|
+
readonly activeSessionKey?: Accessor<string | null>;
|
|
59
65
|
readonly activePaneId?: Accessor<string | null>;
|
|
60
|
-
readonly onOpen: (
|
|
66
|
+
readonly onOpen: (
|
|
67
|
+
machineId: string,
|
|
68
|
+
sessionName: string,
|
|
69
|
+
source: "keyboard" | "mouse",
|
|
70
|
+
sessionKey?: string,
|
|
71
|
+
) => void;
|
|
72
|
+
readonly onSelectServer?: (machineId: string, server: TmuxServerScope) => void;
|
|
61
73
|
readonly onSelectMachine: (machineId: string, source: "keyboard" | "mouse") => void;
|
|
62
74
|
readonly onOpenAgent?: (
|
|
63
75
|
machineId: string,
|
|
@@ -92,6 +104,8 @@ type Row = {
|
|
|
92
104
|
session?: ApplicationMachineGroup["sessions"][number];
|
|
93
105
|
agent?: ApplicationMachineAgent;
|
|
94
106
|
agentHeading?: boolean;
|
|
107
|
+
serverHeading?: string;
|
|
108
|
+
server?: TmuxServerDescriptor;
|
|
95
109
|
};
|
|
96
110
|
/** Pure machine navigation. All connection and session authority stays with the caller. */
|
|
97
111
|
export function ApplicationMachineSidebar(props: {
|
|
@@ -145,9 +159,18 @@ export function ApplicationMachineSidebar(props: {
|
|
|
145
159
|
? row.group.state === "ready" &&
|
|
146
160
|
!row.agent.disabled &&
|
|
147
161
|
row.agent.sessionName === props.model.activeSessionName() &&
|
|
162
|
+
(!props.model.activeSessionKey ||
|
|
163
|
+
row.group.sessions.some(
|
|
164
|
+
(session) =>
|
|
165
|
+
session.id === props.model.activeSessionKey?.() &&
|
|
166
|
+
session.server?.serverId === row.agent?.server?.serverId &&
|
|
167
|
+
session.server?.generation === row.agent?.server?.generation,
|
|
168
|
+
)) &&
|
|
148
169
|
row.agent.paneId !== null &&
|
|
149
170
|
row.agent.paneId === props.model.activePaneId?.()
|
|
150
|
-
:
|
|
171
|
+
: props.model.activeSessionKey
|
|
172
|
+
? row.session?.id === props.model.activeSessionKey()
|
|
173
|
+
: row.session?.name === props.model.activeSessionName());
|
|
151
174
|
const preferenceKey = (group: ApplicationMachineGroup) => group.environmentId ?? group.id;
|
|
152
175
|
const rows = createMemo<readonly Row[]>(() =>
|
|
153
176
|
props.model.groups().flatMap((group) => [
|
|
@@ -158,13 +181,34 @@ export function ApplicationMachineSidebar(props: {
|
|
|
158
181
|
!collapsed().has(preferenceKey(group)) ||
|
|
159
182
|
props.model.favorites?.().includes(session.id) ||
|
|
160
183
|
(group.id === props.model.activeMachineId() &&
|
|
161
|
-
|
|
184
|
+
(props.model.activeSessionKey
|
|
185
|
+
? session.id === props.model.activeSessionKey()
|
|
186
|
+
: session.name === props.model.activeSessionName())),
|
|
162
187
|
)
|
|
163
|
-
.map((session) => ({
|
|
188
|
+
.map((session, index, sessions) => ({
|
|
189
|
+
serverHeading:
|
|
190
|
+
(group.servers?.length ??
|
|
191
|
+
new Set(group.sessions.map((row) => row.server?.serverId)).size) > 1 &&
|
|
192
|
+
session.server &&
|
|
193
|
+
(index === 0 || sessions[index - 1]?.server?.serverId !== session.server.serverId)
|
|
194
|
+
? `${session.serverLabel ?? "Server"} · ${session.server.serverId.slice(-6)}`
|
|
195
|
+
: undefined,
|
|
164
196
|
key: JSON.stringify([group.id, "session", session.id]),
|
|
165
197
|
group,
|
|
166
198
|
session,
|
|
167
199
|
})),
|
|
200
|
+
...(collapsed().has(preferenceKey(group))
|
|
201
|
+
? []
|
|
202
|
+
: (group.servers ?? [])
|
|
203
|
+
.filter(
|
|
204
|
+
(server) =>
|
|
205
|
+
!group.sessions.some((session) => session.server?.serverId === server.serverId),
|
|
206
|
+
)
|
|
207
|
+
.map((server) => ({
|
|
208
|
+
key: JSON.stringify([group.id, "server", server.serverId]),
|
|
209
|
+
group,
|
|
210
|
+
server,
|
|
211
|
+
}))),
|
|
168
212
|
...(!collapsed().has(preferenceKey(group))
|
|
169
213
|
? (group.agents ?? []).map((agent, index) => ({
|
|
170
214
|
key: JSON.stringify([group.id, "agent", agent.id]),
|
|
@@ -193,7 +237,11 @@ export function ApplicationMachineSidebar(props: {
|
|
|
193
237
|
const activity = (row: Row) =>
|
|
194
238
|
summarizeFleetActivity(
|
|
195
239
|
(row.group.agents ?? []).filter(
|
|
196
|
-
(agent) =>
|
|
240
|
+
(agent) =>
|
|
241
|
+
!row.session ||
|
|
242
|
+
(agent.sessionName === row.session.name &&
|
|
243
|
+
agent.server?.serverId === row.session.server?.serverId &&
|
|
244
|
+
agent.server?.generation === row.session.server?.generation),
|
|
197
245
|
),
|
|
198
246
|
row.group.state === "ready" && row.group.agentsAvailable !== false && !row.session?.disabled,
|
|
199
247
|
);
|
|
@@ -229,6 +277,14 @@ export function ApplicationMachineSidebar(props: {
|
|
|
229
277
|
setSelectedKey(row.key);
|
|
230
278
|
setLocalFocused(true);
|
|
231
279
|
props.model.onFocus?.();
|
|
280
|
+
if (row.server) {
|
|
281
|
+
if (row.server.state === "online")
|
|
282
|
+
props.model.onSelectServer?.(row.group.id, {
|
|
283
|
+
serverId: row.server.serverId,
|
|
284
|
+
generation: row.server.generation,
|
|
285
|
+
});
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
232
288
|
if (row.agent) {
|
|
233
289
|
if (
|
|
234
290
|
row.group.state === "ready" &&
|
|
@@ -242,7 +298,7 @@ export function ApplicationMachineSidebar(props: {
|
|
|
242
298
|
}
|
|
243
299
|
} else if (row.session) {
|
|
244
300
|
if (row.group.state === "ready" && !row.session.disabled)
|
|
245
|
-
props.model.onOpen(row.group.id, row.session.name, source);
|
|
301
|
+
props.model.onOpen(row.group.id, row.session.name, source, row.session.id);
|
|
246
302
|
} else if (
|
|
247
303
|
row.group.state !== "ready" ||
|
|
248
304
|
(row.group.sessions.length === 0 && !row.group.agents?.length)
|
|
@@ -252,7 +308,8 @@ export function ApplicationMachineSidebar(props: {
|
|
|
252
308
|
};
|
|
253
309
|
const revealFocusedRow = () => {
|
|
254
310
|
if (!focused() || !scroll) return;
|
|
255
|
-
const rowHeight = (row: Row) =>
|
|
311
|
+
const rowHeight = (row: Row) =>
|
|
312
|
+
row.agent ? (row.agentHeading ? 3 : 2) : row.serverHeading ? 2 : 1;
|
|
256
313
|
const y = rows()
|
|
257
314
|
.slice(0, index())
|
|
258
315
|
.reduce((sum, row) => sum + rowHeight(row), 0);
|
|
@@ -457,6 +514,12 @@ export function ApplicationMachineSidebar(props: {
|
|
|
457
514
|
get agent() {
|
|
458
515
|
return current().agent;
|
|
459
516
|
},
|
|
517
|
+
get server() {
|
|
518
|
+
return current().server;
|
|
519
|
+
},
|
|
520
|
+
get serverHeading() {
|
|
521
|
+
return current().serverHeading;
|
|
522
|
+
},
|
|
460
523
|
get agentHeading() {
|
|
461
524
|
return current().agentHeading;
|
|
462
525
|
},
|
|
@@ -464,10 +527,23 @@ export function ApplicationMachineSidebar(props: {
|
|
|
464
527
|
return (
|
|
465
528
|
<box
|
|
466
529
|
width={Math.max(1, props.width - 1)}
|
|
467
|
-
height={row.agent ? (row.agentHeading ? 3 : 2) : 1}
|
|
530
|
+
height={row.agent ? (row.agentHeading ? 3 : 2) : row.serverHeading ? 2 : 1}
|
|
468
531
|
flexShrink={0}
|
|
469
532
|
flexDirection="column"
|
|
470
533
|
>
|
|
534
|
+
<Show when={row.serverHeading}>
|
|
535
|
+
<NavigationRow
|
|
536
|
+
theme={props.theme}
|
|
537
|
+
width={Math.max(1, props.width - 1)}
|
|
538
|
+
id={`server:${row.group.id}:${row.session?.server?.serverId}`}
|
|
539
|
+
label={row.serverHeading ?? "Server"}
|
|
540
|
+
marker=" ▾"
|
|
541
|
+
onActivate={() => {
|
|
542
|
+
if (row.session?.server)
|
|
543
|
+
props.model.onSelectServer?.(row.group.id, row.session.server);
|
|
544
|
+
}}
|
|
545
|
+
/>
|
|
546
|
+
</Show>
|
|
471
547
|
<Show when={row.agentHeading}>
|
|
472
548
|
<text height={1} fg={props.theme.roles.text.secondary}>
|
|
473
549
|
{" "}
|
|
@@ -480,43 +556,51 @@ export function ApplicationMachineSidebar(props: {
|
|
|
480
556
|
width={Math.max(1, props.width - 1)}
|
|
481
557
|
labelColor={!row.agent && !row.session ? fleetHostColor(row.group) : undefined}
|
|
482
558
|
label={
|
|
483
|
-
row.
|
|
484
|
-
? row.
|
|
485
|
-
: row.
|
|
486
|
-
?
|
|
487
|
-
: row.
|
|
559
|
+
row.server
|
|
560
|
+
? ` ${row.server.label} · ${row.server.serverId.slice(-6)}`
|
|
561
|
+
: row.agent
|
|
562
|
+
? row.agent.name
|
|
563
|
+
: row.session
|
|
564
|
+
? friendlySessionLabel(row.session.name)
|
|
565
|
+
: row.group.label
|
|
488
566
|
}
|
|
489
567
|
marker={
|
|
490
|
-
row.
|
|
491
|
-
?
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
? "
|
|
503
|
-
:
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
:
|
|
568
|
+
row.server
|
|
569
|
+
? " "
|
|
570
|
+
: row.agent
|
|
571
|
+
? active(row)
|
|
572
|
+
? row.agent.attention
|
|
573
|
+
? "›!"
|
|
574
|
+
: "›"
|
|
575
|
+
: row.agent.attention
|
|
576
|
+
? "!"
|
|
577
|
+
: "•"
|
|
578
|
+
: row.session
|
|
579
|
+
? props.model.favorites?.().includes(row.session.id)
|
|
580
|
+
? " ★"
|
|
581
|
+
: active(row)
|
|
582
|
+
? " ›"
|
|
583
|
+
: " "
|
|
584
|
+
: collapsed().has(preferenceKey(row.group))
|
|
585
|
+
? "▸"
|
|
586
|
+
: "▾"
|
|
507
587
|
}
|
|
508
588
|
detail={
|
|
509
|
-
row.
|
|
510
|
-
? row.
|
|
511
|
-
? "
|
|
512
|
-
:
|
|
513
|
-
: row.
|
|
514
|
-
? row.group.state !== "ready" || row.
|
|
589
|
+
row.server
|
|
590
|
+
? row.server.state === "offline"
|
|
591
|
+
? "offline"
|
|
592
|
+
: "empty"
|
|
593
|
+
: row.agent
|
|
594
|
+
? row.group.state !== "ready" || row.agent.disabled
|
|
515
595
|
? "unavailable"
|
|
516
|
-
:
|
|
517
|
-
: row.
|
|
518
|
-
?
|
|
519
|
-
|
|
596
|
+
: `[${terminalAgentStatusLabel(row.agent.activity)}]`
|
|
597
|
+
: row.session
|
|
598
|
+
? row.group.state !== "ready" || row.session.disabled
|
|
599
|
+
? "unavailable"
|
|
600
|
+
: `${row.session.paneCount}p${row.group.agents?.length ? ` ${activity(row).label}` : ""}`
|
|
601
|
+
: row.group.agents?.length && row.group.state === "ready"
|
|
602
|
+
? activity(row).label
|
|
603
|
+
: `${connectionDetail(row.group)}${row.group.agents?.length ? " ?" : ""}`
|
|
520
604
|
}
|
|
521
605
|
selected={Boolean((row.session || row.agent) && active(row))}
|
|
522
606
|
focused={Boolean(focused() && row.key === selectedKey())}
|
|
@@ -53,6 +53,8 @@ export function ApplicationPalettePreview(props: {
|
|
|
53
53
|
const identity = () =>
|
|
54
54
|
JSON.stringify([
|
|
55
55
|
target()?.machineId,
|
|
56
|
+
target()?.server?.serverId,
|
|
57
|
+
target()?.server?.generation,
|
|
56
58
|
target()?.liveSessionId,
|
|
57
59
|
target()?.daemonInstanceId,
|
|
58
60
|
paneId(),
|
|
@@ -77,6 +79,7 @@ export function ApplicationPalettePreview(props: {
|
|
|
77
79
|
fleet &&
|
|
78
80
|
Boolean(fleet.liveSessionId) &&
|
|
79
81
|
!fleet.disabled &&
|
|
82
|
+
(!fleet.server || fleet.server.generation === fleet.daemonInstanceId) &&
|
|
80
83
|
handle?.endpoint().state === "ready" &&
|
|
81
84
|
handle.read()?.instanceId === fleet.daemonInstanceId;
|
|
82
85
|
owner.select(
|
|
@@ -56,10 +56,13 @@ const LIFECYCLE_RUNTIME_PHASES = new Set([
|
|
|
56
56
|
]);
|
|
57
57
|
|
|
58
58
|
const lifecycleRecords = new Map<string, string>();
|
|
59
|
+
let closing = false;
|
|
60
|
+
let closePromise: Promise<void> | null = null;
|
|
59
61
|
|
|
60
62
|
function serializeMark(phase: string, details?: Readonly<Record<string, unknown>>): string | null {
|
|
61
63
|
if (
|
|
62
64
|
!stream ||
|
|
65
|
+
closing ||
|
|
63
66
|
(!tuiPerfStream &&
|
|
64
67
|
!LIFECYCLE_PHASES.has(phase) &&
|
|
65
68
|
!(
|
|
@@ -160,10 +163,19 @@ async function flushTuiPerfMarks(): Promise<void> {
|
|
|
160
163
|
});
|
|
161
164
|
}
|
|
162
165
|
|
|
163
|
-
export
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
export function closeTuiPerfMarks(): Promise<void> {
|
|
167
|
+
if (closePromise) return closePromise;
|
|
168
|
+
// Renderer/runtime callbacks can still emit marks during asynchronous teardown.
|
|
169
|
+
// Stop accepting them before yielding, and let every caller await one close.
|
|
170
|
+
closing = true;
|
|
171
|
+
closePromise = (async () => {
|
|
172
|
+
if (!stream) return;
|
|
173
|
+
await flushTuiPerfMarks();
|
|
174
|
+
// No drain callback may enqueue another critical record after end().
|
|
175
|
+
stream.off("drain", drain);
|
|
176
|
+
await new Promise<void>((resolveClose) => stream.end(resolveClose));
|
|
177
|
+
// Keep the error listener through the underlying file descriptor teardown;
|
|
178
|
+
// an asynchronous close error must remain a logging failure, not a crash.
|
|
179
|
+
})();
|
|
180
|
+
return closePromise;
|
|
169
181
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TmuxServerIdSchemaZ } from "@tmux-ide/contracts";
|
|
1
2
|
import { parseArgs } from "node:util";
|
|
2
3
|
|
|
3
4
|
import { loadAppConfig, type AppConfig } from "../../../lib/app-config.ts";
|
|
@@ -6,11 +7,13 @@ import { tuiPerfMark } from "./application-performance-log.ts";
|
|
|
6
7
|
|
|
7
8
|
export interface ApplicationArgs {
|
|
8
9
|
readonly target: string | null;
|
|
10
|
+
readonly serverId?: string | null;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export interface ApplicationConfig {
|
|
12
14
|
readonly app: AppConfig;
|
|
13
15
|
readonly target: string | null;
|
|
16
|
+
readonly serverId?: string | null;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export interface StartApplicationRootOptions {
|
|
@@ -31,11 +34,17 @@ export const parseApplicationArgs = (argv: readonly string[]): ApplicationArgs =
|
|
|
31
34
|
args: [...argv],
|
|
32
35
|
allowPositionals: true,
|
|
33
36
|
strict: false,
|
|
34
|
-
options: { target: { type: "string" } },
|
|
37
|
+
options: { target: { type: "string" }, server: { type: "string" } },
|
|
35
38
|
});
|
|
36
39
|
const positional = parsed.positionals.find((value) => value !== "app") ?? null;
|
|
37
40
|
const target = typeof parsed.values.target === "string" ? parsed.values.target : positional;
|
|
38
|
-
return Object.freeze({
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
target: target && target !== "home" ? target : null,
|
|
43
|
+
serverId:
|
|
44
|
+
typeof parsed.values.server === "string"
|
|
45
|
+
? TmuxServerIdSchemaZ.parse(parsed.values.server)
|
|
46
|
+
: null,
|
|
47
|
+
});
|
|
39
48
|
};
|
|
40
49
|
|
|
41
50
|
export async function loadApplicationConfig(args: ApplicationArgs): Promise<ApplicationConfig> {
|
|
@@ -43,5 +52,5 @@ export async function loadApplicationConfig(args: ApplicationArgs): Promise<Appl
|
|
|
43
52
|
// Home discovery is daemon-authoritative and remains live after mount. The
|
|
44
53
|
// immutable bootstrap config only carries an explicit user target.
|
|
45
54
|
tuiPerfMark("config-load-end", { target: args.target });
|
|
46
|
-
return Object.freeze({ app: loadAppConfig(), target: args.target });
|
|
55
|
+
return Object.freeze({ app: loadAppConfig(), target: args.target, serverId: args.serverId });
|
|
47
56
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { TmuxServerScope } from "@tmux-ide/contracts";
|
|
2
|
+
import { terminalWindowActionCallbacks } from "./application-terminal-workspace-policy.ts";
|
|
1
3
|
import { applicationRouteConnection } from "./application-route-connection.ts";
|
|
2
4
|
import { ApplicationMachineOverlays } from "./application-machine-overlays.tsx";
|
|
3
|
-
import { handleFleetShortcut } from "./application-machine-navigation.ts";
|
|
4
5
|
import { applicationMachineAuthorityManager } from "./application-machine-authority.ts";
|
|
5
6
|
import { createApplicationMachineAgentNavigator } from "./application-machine-agent-navigation.ts";
|
|
6
7
|
import { createApplicationMachineNavigation } from "./application-machine-navigation.ts";
|
|
8
|
+
import { handleFleetShortcut } from "./application-machine-navigation.ts";
|
|
7
9
|
import { disposeApplicationDaemonAuthority } from "./application-daemon-authority.ts";
|
|
8
10
|
import { createTerminalLinkOpener } from "./terminal-link-opener.ts";
|
|
9
11
|
import { createApplicationPaneActivityOwner } from "./application-pane-activity-owner.ts";
|
|
@@ -29,14 +31,14 @@ import {
|
|
|
29
31
|
type StartApplicationRootOptions,
|
|
30
32
|
} from "./application-root-configuration.ts";
|
|
31
33
|
import { createApplicationHomeCatalogOwner } from "./application-home-catalog-owner.ts";
|
|
32
|
-
import {
|
|
34
|
+
import { createApplicationHomeExperience } from "./application-home-experience.ts";
|
|
33
35
|
import { ApplicationShellView, applicationShellKeyAction } from "./application-shell-view.tsx";
|
|
34
36
|
import {
|
|
35
37
|
applicationGenerationNavigationKey,
|
|
36
38
|
createApplicationGenerationStarter,
|
|
37
39
|
} from "./application-generation-starter.ts";
|
|
38
40
|
import { createApplicationInputReadiness } from "./application-input-readiness.ts";
|
|
39
|
-
import {
|
|
41
|
+
import { createApplicationAppearanceRendererBinding } from "./application-theme-repaint.ts";
|
|
40
42
|
import { createApplicationTerminalInteractionController } from "./application-terminal-interaction-controller.ts";
|
|
41
43
|
import {
|
|
42
44
|
createApplicationHostFocusRecovery,
|
|
@@ -174,6 +176,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
174
176
|
const makeSessionOwner = (
|
|
175
177
|
machineId = applicationMachineAuthorityManager.snapshot().selectedMachineId,
|
|
176
178
|
expectedLiveSessionId?: string,
|
|
179
|
+
server?: TmuxServerScope,
|
|
177
180
|
) => {
|
|
178
181
|
const ownedEpoch = ++sessionOwnerEpoch;
|
|
179
182
|
connectionProgress.replaceOwner();
|
|
@@ -181,6 +184,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
181
184
|
applicationMachineAuthorityManager.getMachine(machineId)!,
|
|
182
185
|
expectedLiveSessionId,
|
|
183
186
|
tuiLifecycleStream ? tuiPerfMark : undefined,
|
|
187
|
+
server,
|
|
184
188
|
);
|
|
185
189
|
return createOpenTuiSessionOwner({
|
|
186
190
|
onStartupFailure: (sessionName, failure) => {
|
|
@@ -315,19 +319,18 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
315
319
|
| ReturnType<typeof createApplicationMachineAgentNavigator>
|
|
316
320
|
| undefined;
|
|
317
321
|
const machines = createApplicationMachineNavigation({
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
322
|
+
attachedGeneration: generation,
|
|
323
|
+
resetWorkspace(machineId, expectedLiveSessionId, server) {
|
|
324
|
+
void initialPreparation?.preparedConnection
|
|
325
|
+
.then((connection) => connection?.dispose())
|
|
326
|
+
.catch(() => undefined);
|
|
327
|
+
initialPreparation = null;
|
|
325
328
|
interaction?.adoptGeneration(null);
|
|
326
329
|
setGeneration(null);
|
|
327
330
|
shellBinding.adoptGeneration(null);
|
|
328
331
|
terminalHostFocus.adopt(null);
|
|
329
332
|
void sessionOwner?.dispose().catch(() => undefined);
|
|
330
|
-
sessionOwner = makeSessionOwner(machineId, expectedLiveSessionId);
|
|
333
|
+
sessionOwner = makeSessionOwner(machineId, expectedLiveSessionId, server);
|
|
331
334
|
},
|
|
332
335
|
cancelOpen: () => {
|
|
333
336
|
machineAgentNavigator?.cancel();
|
|
@@ -361,9 +364,11 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
361
364
|
onCleanup(() => machineAgentNavigator?.dispose());
|
|
362
365
|
const homeCatalog = createApplicationHomeCatalogOwner({
|
|
363
366
|
lifecycle,
|
|
364
|
-
automaticOpen: config.target === null && machines.automaticOpen,
|
|
367
|
+
automaticOpen: config.target === null && !config.serverId && machines.automaticOpen,
|
|
365
368
|
automaticOpenAllowed: machines.automaticOpenAllowed,
|
|
366
369
|
catalog: machines.catalog.selectedCatalog,
|
|
370
|
+
openCatalogSession: (session) =>
|
|
371
|
+
machines.openSelectedSession(session.name, "keyboard", session.id),
|
|
367
372
|
startGeneration,
|
|
368
373
|
setNote: appearance.setNote,
|
|
369
374
|
});
|
|
@@ -378,10 +383,16 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
378
383
|
componentKeyboardRoutes.dispose();
|
|
379
384
|
sessionFocusOwner?.dispose();
|
|
380
385
|
});
|
|
381
|
-
const { homeAgents, paneRename, paletteCommands, paletteCommandList, openAgent } =
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
386
|
+
const { homeAgents, paneRename, paletteCommands, paletteCommandList, openAgent, tour } =
|
|
387
|
+
createApplicationHomeExperience({
|
|
388
|
+
machines,
|
|
389
|
+
lifecycle,
|
|
390
|
+
generation,
|
|
391
|
+
generationMachineId,
|
|
392
|
+
layoutSnapshot,
|
|
393
|
+
appearance,
|
|
394
|
+
dimensions,
|
|
395
|
+
paletteModalOpen,
|
|
385
396
|
focusedPane,
|
|
386
397
|
catalog: homeCatalog,
|
|
387
398
|
activeSurface,
|
|
@@ -398,16 +409,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
398
409
|
setSurface,
|
|
399
410
|
setNote: setTransientNote,
|
|
400
411
|
});
|
|
401
|
-
|
|
402
|
-
createEffect(() => {
|
|
403
|
-
const nextAppearance = appearance.appearance();
|
|
404
|
-
paintedAppearanceGeneration = applyApplicationAppearanceToRenderer(
|
|
405
|
-
renderer,
|
|
406
|
-
nextAppearance.theme,
|
|
407
|
-
nextAppearance.generation,
|
|
408
|
-
paintedAppearanceGeneration,
|
|
409
|
-
);
|
|
410
|
-
});
|
|
412
|
+
createApplicationAppearanceRendererBinding(renderer, appearance);
|
|
411
413
|
createEffect(() => {
|
|
412
414
|
const currentShell = shell();
|
|
413
415
|
semanticViewportResize.adopt(dimensions(), currentShell.semantic, generation());
|
|
@@ -417,11 +419,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
417
419
|
useKeyboard((event) => {
|
|
418
420
|
noteHostInteraction();
|
|
419
421
|
const name = event.name.toLowerCase();
|
|
420
|
-
if (paletteModalOpen()) {
|
|
421
|
-
componentKeyboardRoutes.route(event);
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
if (machines.switching()) {
|
|
422
|
+
if (paletteModalOpen() || machines.switching()) {
|
|
425
423
|
componentKeyboardRoutes.route(event);
|
|
426
424
|
return;
|
|
427
425
|
}
|
|
@@ -525,7 +523,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
525
523
|
});
|
|
526
524
|
onMount(() => {
|
|
527
525
|
tuiPerfMark("solid-mounted");
|
|
528
|
-
machines.start(config.target);
|
|
526
|
+
machines.start(config.target, config.serverId);
|
|
529
527
|
});
|
|
530
528
|
const resizeIngress = tuiPerfStream ? interaction.beginResizePointerIngress : undefined;
|
|
531
529
|
const applicationMouseIngress = applicationMousePointerIngressCapability(
|
|
@@ -541,6 +539,8 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
541
539
|
machineSidebar={machines.sidebar}
|
|
542
540
|
appearanceOwner={appearance}
|
|
543
541
|
homeAgents={homeAgents.presentation}
|
|
542
|
+
onOpenTutorial={tour.open}
|
|
543
|
+
tutorialLabel={tour.label()}
|
|
544
544
|
dimensions={dimensions}
|
|
545
545
|
surface={activeSurface}
|
|
546
546
|
semantic={() => shell().semantic}
|
|
@@ -591,7 +591,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
591
591
|
onOpenSession={recoverHostFocus((sessionName, source) => {
|
|
592
592
|
machineAgentNavigator?.cancel();
|
|
593
593
|
homeAgents?.cancel();
|
|
594
|
-
void
|
|
594
|
+
void machines.openSelectedSession(sessionName, source);
|
|
595
595
|
})}
|
|
596
596
|
onOpenAgent={recoverHostFocus((sessionName, paneId, source) => {
|
|
597
597
|
machineAgentNavigator?.cancel();
|
|
@@ -600,9 +600,12 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
600
600
|
})}
|
|
601
601
|
onSetPaletteOpen={recoverHostFocus(paletteCommands.setOpen)}
|
|
602
602
|
onPaletteActivate={recoverHostFocus(paletteCommands.activate)}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
603
|
+
{...terminalWindowActionCallbacks(
|
|
604
|
+
interaction,
|
|
605
|
+
setTransientNote,
|
|
606
|
+
recoverHostFocus,
|
|
607
|
+
() => machineAgentNavigator?.cancel(),
|
|
608
|
+
)}
|
|
606
609
|
onCreateWindow={recoverHostFocus(() =>
|
|
607
610
|
paletteCommands.activate("new-window", "mouse"),
|
|
608
611
|
)}
|
|
@@ -616,10 +619,6 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
616
619
|
onCancelPaneRename={recoverHostFocus(paneRename.cancel)}
|
|
617
620
|
onSubmitPaneRename={recoverHostFocus(paneRename.submit)}
|
|
618
621
|
onDismissNotification={recoverHostFocus(() => setTransientNote(null))}
|
|
619
|
-
onSelectPane={recoverHostFocus((paneId, source) => {
|
|
620
|
-
machineAgentNavigator?.cancel();
|
|
621
|
-
interaction.selectPane(paneId, source);
|
|
622
|
-
})}
|
|
623
622
|
onResizePreview={recoverHostFocus(interaction.previewPaneResize)}
|
|
624
623
|
onResizePane={recoverHostFocus(interaction.resizePane)}
|
|
625
624
|
onCancelResize={interaction.cancelPaneResize}
|
|
@@ -636,6 +635,7 @@ export async function startApplicationRoot(options: StartApplicationRootOptions
|
|
|
636
635
|
onWindowPresented={tuiPerfStream ? interaction.observeWindowPresentation : undefined}
|
|
637
636
|
onInteraction={() => noteHostInteraction()}
|
|
638
637
|
/>
|
|
638
|
+
<tour.Coach />
|
|
639
639
|
<ApplicationMachineOverlays
|
|
640
640
|
machines={machines}
|
|
641
641
|
active={rendererFocused()}
|