@monotykamary/localterm-server 2.66.8 → 2.66.10
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/agent-git-status.d.ts +3 -0
- package/dist/agent-git-status.d.ts.map +1 -0
- package/dist/agent-git-status.js +46 -0
- package/dist/agent-git-status.js.map +1 -0
- package/dist/agent-log-utils.d.ts +18 -0
- package/dist/agent-log-utils.d.ts.map +1 -0
- package/dist/agent-log-utils.js +123 -0
- package/dist/agent-log-utils.js.map +1 -0
- package/dist/agent-models.d.ts +4 -0
- package/dist/agent-models.d.ts.map +1 -0
- package/dist/agent-models.js +100 -0
- package/dist/agent-models.js.map +1 -0
- package/dist/agent-runner.d.ts +3 -5
- package/dist/agent-runner.d.ts.map +1 -1
- package/dist/agent-runner.js +8 -522
- package/dist/agent-runner.js.map +1 -1
- package/dist/agent-session-reader.d.ts +3 -0
- package/dist/agent-session-reader.d.ts.map +1 -0
- package/dist/agent-session-reader.js +113 -0
- package/dist/agent-session-reader.js.map +1 -0
- package/dist/build-pty-environment.d.ts +8 -0
- package/dist/build-pty-environment.d.ts.map +1 -0
- package/dist/build-pty-environment.js +44 -0
- package/dist/build-pty-environment.js.map +1 -0
- package/dist/caffeinate-automatic-detector.d.ts +57 -0
- package/dist/caffeinate-automatic-detector.d.ts.map +1 -0
- package/dist/caffeinate-automatic-detector.js +275 -0
- package/dist/caffeinate-automatic-detector.js.map +1 -0
- package/dist/caffeinate-battery-guard.d.ts +35 -0
- package/dist/caffeinate-battery-guard.d.ts.map +1 -0
- package/dist/caffeinate-battery-guard.js +190 -0
- package/dist/caffeinate-battery-guard.js.map +1 -0
- package/dist/caffeinate-manager.d.ts +5 -31
- package/dist/caffeinate-manager.d.ts.map +1 -1
- package/dist/caffeinate-manager.js +55 -400
- package/dist/caffeinate-manager.js.map +1 -1
- package/dist/cdp/cdp-client.d.ts +4 -70
- package/dist/cdp/cdp-client.d.ts.map +1 -1
- package/dist/cdp/cdp-client.js +58 -418
- package/dist/cdp/cdp-client.js.map +1 -1
- package/dist/cdp/cdp-connection.d.ts +72 -0
- package/dist/cdp/cdp-connection.d.ts.map +1 -0
- package/dist/cdp/cdp-connection.js +272 -0
- package/dist/cdp/cdp-connection.js.map +1 -0
- package/dist/cdp/constants.d.ts +6 -0
- package/dist/cdp/constants.d.ts.map +1 -0
- package/dist/cdp/constants.js +9 -0
- package/dist/cdp/constants.js.map +1 -0
- package/dist/cdp/target-registry.d.ts +41 -0
- package/dist/cdp/target-registry.d.ts.map +1 -0
- package/dist/cdp/target-registry.js +118 -0
- package/dist/cdp/target-registry.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/git-branch-metadata.d.ts +11 -0
- package/dist/git-branch-metadata.d.ts.map +1 -0
- package/dist/git-branch-metadata.js +85 -0
- package/dist/git-branch-metadata.js.map +1 -0
- package/dist/git-diff-cache.d.ts +13 -0
- package/dist/git-diff-cache.d.ts.map +1 -0
- package/dist/git-diff-cache.js +32 -0
- package/dist/git-diff-cache.js.map +1 -0
- package/dist/git-diff-parser.d.ts +15 -0
- package/dist/git-diff-parser.d.ts.map +1 -0
- package/dist/git-diff-parser.js +196 -0
- package/dist/git-diff-parser.js.map +1 -0
- package/dist/git-diff-service.d.ts +10 -0
- package/dist/git-diff-service.d.ts.map +1 -0
- package/dist/git-diff-service.js +395 -0
- package/dist/git-diff-service.js.map +1 -0
- package/dist/git-diff.d.ts +8 -41
- package/dist/git-diff.d.ts.map +1 -1
- package/dist/git-diff.js +5 -944
- package/dist/git-diff.js.map +1 -1
- package/dist/github-pr.d.ts +32 -0
- package/dist/github-pr.d.ts.map +1 -0
- package/dist/github-pr.js +266 -0
- package/dist/github-pr.js.map +1 -0
- package/dist/pi-binary-resolver.d.ts +6 -0
- package/dist/pi-binary-resolver.d.ts.map +1 -0
- package/dist/pi-binary-resolver.js +70 -0
- package/dist/pi-binary-resolver.js.map +1 -0
- package/dist/pi-rpc-client.d.ts +14 -0
- package/dist/pi-rpc-client.d.ts.map +1 -0
- package/dist/pi-rpc-client.js +87 -0
- package/dist/pi-rpc-client.js.map +1 -0
- package/dist/session-client-hub.d.ts +57 -0
- package/dist/session-client-hub.d.ts.map +1 -0
- package/dist/session-client-hub.js +435 -0
- package/dist/session-client-hub.js.map +1 -0
- package/dist/session-command-executor.d.ts +14 -0
- package/dist/session-command-executor.d.ts.map +1 -0
- package/dist/session-command-executor.js +207 -0
- package/dist/session-command-executor.js.map +1 -0
- package/dist/session-git-event-bridge.d.ts +16 -0
- package/dist/session-git-event-bridge.d.ts.map +1 -0
- package/dist/session-git-event-bridge.js +56 -0
- package/dist/session-git-event-bridge.js.map +1 -0
- package/dist/session-lifecycle-policy.d.ts +15 -0
- package/dist/session-lifecycle-policy.d.ts.map +1 -0
- package/dist/session-lifecycle-policy.js +105 -0
- package/dist/session-lifecycle-policy.js.map +1 -0
- package/dist/session-manager.d.ts +11 -42
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +72 -987
- package/dist/session-manager.js.map +1 -1
- package/dist/session-output-coordinator.d.ts +21 -0
- package/dist/session-output-coordinator.d.ts.map +1 -0
- package/dist/session-output-coordinator.js +134 -0
- package/dist/session-output-coordinator.js.map +1 -0
- package/dist/session-output-transport.d.ts +22 -0
- package/dist/session-output-transport.d.ts.map +1 -0
- package/dist/session-output-transport.js +160 -0
- package/dist/session-output-transport.js.map +1 -0
- package/dist/session.d.ts +0 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +11 -258
- package/dist/session.js.map +1 -1
- package/dist/shell-hook-builder.d.ts +16 -0
- package/dist/shell-hook-builder.d.ts.map +1 -0
- package/dist/shell-hook-builder.js +230 -0
- package/dist/shell-hook-builder.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { GitMetadataCoordinator } from "./git-metadata-coordinator.js";
|
|
2
|
+
import type { ManagedSession } from "./session-manager.js";
|
|
3
|
+
import { SessionOutputTransport } from "./session-output-transport.js";
|
|
4
|
+
import type { CompressMode } from "./schemas.js";
|
|
5
|
+
import type { GitBranchPr, ServerToClientMessage, SessionClientProfile } from "./types.js";
|
|
6
|
+
import type { SessionOwner } from "./identity/types.js";
|
|
7
|
+
import type { ClientSocket } from "./utils/ws-socket.js";
|
|
8
|
+
import type { WorkspaceEntry } from "./workspace-store.js";
|
|
9
|
+
interface SessionClientHubOptions {
|
|
10
|
+
outputTransport: SessionOutputTransport;
|
|
11
|
+
sendControl: (ws: ClientSocket, payload: ServerToClientMessage) => void;
|
|
12
|
+
pendingPromoteTimeoutMs: number;
|
|
13
|
+
sessionFor: (id: string, owner: SessionOwner) => ManagedSession | null;
|
|
14
|
+
cancelGrace: (managed: ManagedSession) => void;
|
|
15
|
+
startGrace: (managed: ManagedSession) => void;
|
|
16
|
+
onSessionActivity: () => void;
|
|
17
|
+
}
|
|
18
|
+
export declare class SessionClientHub {
|
|
19
|
+
private readonly wsToClient;
|
|
20
|
+
private readonly coordinatorsByCwd;
|
|
21
|
+
private readonly outputTransport;
|
|
22
|
+
private readonly sendControl;
|
|
23
|
+
private readonly pendingPromoteTimeoutMs;
|
|
24
|
+
private readonly sessionFor;
|
|
25
|
+
private readonly cancelGrace;
|
|
26
|
+
private readonly startGrace;
|
|
27
|
+
private readonly onSessionActivity;
|
|
28
|
+
constructor(options: SessionClientHubOptions);
|
|
29
|
+
clientProfilesFor(managed: ManagedSession): SessionClientProfile[];
|
|
30
|
+
workspaceEntries(sessions: Iterable<ManagedSession>): WorkspaceEntry[];
|
|
31
|
+
clientProfile(ws: ClientSocket): {
|
|
32
|
+
owner: SessionOwner;
|
|
33
|
+
windowId: string;
|
|
34
|
+
} | null;
|
|
35
|
+
attachedClientCount(sessions: Iterable<ManagedSession>, owner: SessionOwner, windowId: string): number;
|
|
36
|
+
attach(ws: ClientSocket, id: string, owner?: SessionOwner, windowId?: string): ManagedSession | null;
|
|
37
|
+
promote(ws: ClientSocket, replay: boolean, compress?: CompressMode): Promise<void>;
|
|
38
|
+
writeInput(ws: ClientSocket, data: string): void;
|
|
39
|
+
writeTerminalResponse(ws: ClientSocket, data: string): void;
|
|
40
|
+
private ensureTerminalResponder;
|
|
41
|
+
private assignTerminalResponder;
|
|
42
|
+
resize(ws: ClientSocket, cols: number, rows: number, pixelWidth?: number, pixelHeight?: number): void;
|
|
43
|
+
detach(ws: ClientSocket): void;
|
|
44
|
+
broadcastToOwner(managed: ManagedSession, payload: ServerToClientMessage): void;
|
|
45
|
+
private recomputeResize;
|
|
46
|
+
moveClientCoordinators(managed: ManagedSession, cwd: string): void;
|
|
47
|
+
private moveClientCoordinator;
|
|
48
|
+
tearDown(managed: ManagedSession): void;
|
|
49
|
+
private releaseClient;
|
|
50
|
+
dispose(): void;
|
|
51
|
+
coordinatorForCwd(cwd: string): GitMetadataCoordinator;
|
|
52
|
+
private releaseCoordinator;
|
|
53
|
+
broadcastGitBranchPr(cwd: string, pr: GitBranchPr | null): void;
|
|
54
|
+
hasCoordinatorFor(cwd: string): boolean;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=session-client-hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-client-hub.d.ts","sourceRoot":"","sources":["../src/session-client-hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { WS_OUTPUT_BROTLI_QUALITY } from "./constants.js";
|
|
3
|
+
import { GitMetadataCoordinator } from "./git-metadata-coordinator.js";
|
|
4
|
+
import { makeBrotliEncoder, SessionOutputTransport } from "./session-output-transport.js";
|
|
5
|
+
export class SessionClientHub {
|
|
6
|
+
wsToClient = new Map();
|
|
7
|
+
coordinatorsByCwd = new Map();
|
|
8
|
+
outputTransport;
|
|
9
|
+
sendControl;
|
|
10
|
+
pendingPromoteTimeoutMs;
|
|
11
|
+
sessionFor;
|
|
12
|
+
cancelGrace;
|
|
13
|
+
startGrace;
|
|
14
|
+
onSessionActivity;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.outputTransport = options.outputTransport;
|
|
17
|
+
this.sendControl = options.sendControl;
|
|
18
|
+
this.pendingPromoteTimeoutMs = options.pendingPromoteTimeoutMs;
|
|
19
|
+
this.sessionFor = options.sessionFor;
|
|
20
|
+
this.cancelGrace = options.cancelGrace;
|
|
21
|
+
this.startGrace = options.startGrace;
|
|
22
|
+
this.onSessionActivity = options.onSessionActivity;
|
|
23
|
+
}
|
|
24
|
+
// The attached clients grouped by their per-browser-profile handle, for the
|
|
25
|
+
// session picker's per-profile peer display. Each entry counts how many of
|
|
26
|
+
// that profile's windows are viewing this PTY; sorted by count desc then id
|
|
27
|
+
// for a stable order (the picker re-ranks its own profile to the front).
|
|
28
|
+
clientProfilesFor(managed) {
|
|
29
|
+
const counts = new Map();
|
|
30
|
+
for (const client of managed.clients) {
|
|
31
|
+
counts.set(client.windowId, (counts.get(client.windowId) ?? 0) + 1);
|
|
32
|
+
}
|
|
33
|
+
return [...counts.entries()]
|
|
34
|
+
.map(([windowId, count]) => ({ windowId, count }))
|
|
35
|
+
.sort((firstProfile, secondProfile) => secondProfile.count - firstProfile.count ||
|
|
36
|
+
firstProfile.windowId.localeCompare(secondProfile.windowId));
|
|
37
|
+
}
|
|
38
|
+
// The persisted workspace manifest: every currently-open tab, grouped by
|
|
39
|
+
// (owner, windowId), recording the live cwd + shell to respawn it in. A
|
|
40
|
+
// session with N attached clients of one windowId contributes N tabs (each
|
|
41
|
+
// viewer is a tab). Automation-run sessions are skipped (their tabs are
|
|
42
|
+
// one-shot), and sessions with no clients (dormant/orphaned) contribute
|
|
43
|
+
// nothing — only tabs that are actively open are restored. Computed from
|
|
44
|
+
// in-memory state, so the daemon snapshots it to disk before a graceful
|
|
45
|
+
// stop (and debounced during life for crash recovery).
|
|
46
|
+
workspaceEntries(sessions) {
|
|
47
|
+
const byKey = new Map();
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
for (const managed of sessions) {
|
|
50
|
+
if (managed.automation)
|
|
51
|
+
continue;
|
|
52
|
+
if (managed.clients.size === 0)
|
|
53
|
+
continue;
|
|
54
|
+
const cwd = managed.session.lastEmittedCwd || managed.session.cwd;
|
|
55
|
+
const shell = managed.session.shell;
|
|
56
|
+
const tab = { cwd, shell };
|
|
57
|
+
for (const client of managed.clients) {
|
|
58
|
+
if (!client.windowId)
|
|
59
|
+
continue;
|
|
60
|
+
const key = `${managed.owner ?? ""}\u0000${client.windowId}`;
|
|
61
|
+
let entry = byKey.get(key);
|
|
62
|
+
if (!entry) {
|
|
63
|
+
entry = { owner: managed.owner, windowId: client.windowId, tabs: [], savedAt: now };
|
|
64
|
+
byKey.set(key, entry);
|
|
65
|
+
}
|
|
66
|
+
entry.tabs.push(tab);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return [...byKey.values()];
|
|
70
|
+
}
|
|
71
|
+
// The (owner, windowId) a socket's tab is viewing, for scoping a CDP
|
|
72
|
+
// workspace restore to the browser profile that just reconnected. Returns
|
|
73
|
+
// null when the socket isn't attached to a session (e.g. a transient
|
|
74
|
+
// mid-detach state).
|
|
75
|
+
clientProfile(ws) {
|
|
76
|
+
const entry = this.wsToClient.get(ws);
|
|
77
|
+
if (!entry)
|
|
78
|
+
return null;
|
|
79
|
+
return { owner: entry.session.owner, windowId: entry.client.windowId };
|
|
80
|
+
}
|
|
81
|
+
// How many of a browser profile's tabs are currently attached to a (non-
|
|
82
|
+
// automation) session — the "already open" count the restore reconciles
|
|
83
|
+
// the persisted manifest against. Surviving tabs that reattach after a
|
|
84
|
+
// daemon restart are counted here so the daemon only opens the deficit.
|
|
85
|
+
attachedClientCount(sessions, owner, windowId) {
|
|
86
|
+
let count = 0;
|
|
87
|
+
for (const managed of sessions) {
|
|
88
|
+
if (owner !== null && managed.owner !== owner)
|
|
89
|
+
continue;
|
|
90
|
+
if (managed.automation)
|
|
91
|
+
continue;
|
|
92
|
+
for (const client of managed.clients)
|
|
93
|
+
if (client.windowId === windowId)
|
|
94
|
+
count++;
|
|
95
|
+
}
|
|
96
|
+
return count;
|
|
97
|
+
}
|
|
98
|
+
// Attach `ws` to a live PTY by id. Returns the session to reattach to, or
|
|
99
|
+
// null when the id is unknown / already exited — the caller spawns fresh.
|
|
100
|
+
attach(ws, id, owner = null, windowId = "") {
|
|
101
|
+
const managed = this.sessionFor(id, owner);
|
|
102
|
+
if (!managed)
|
|
103
|
+
return null;
|
|
104
|
+
// Re-subscribing cancels the no-clients grace timer (if armed): the shell
|
|
105
|
+
// has a viewer again, so it stays alive.
|
|
106
|
+
this.cancelGrace(managed);
|
|
107
|
+
// Notify existing subscribers a peer joined (a mobile ingested this
|
|
108
|
+
// session's share QR) so a host can react — e.g. the desktop's QR modal
|
|
109
|
+
// auto-closes. Gated on existing clients so a fresh spawn's first attach
|
|
110
|
+
// stays silent, and fired before adding the joiner so it isn't told about
|
|
111
|
+
// itself. See peerAttachedMessageSchema for the frame's payload rationale.
|
|
112
|
+
if (managed.clients.size > 0)
|
|
113
|
+
this.outputTransport.broadcast(managed, { type: "peer-attached" });
|
|
114
|
+
const coordinator = this.coordinatorForCwd(managed.session.cwd);
|
|
115
|
+
const client = {
|
|
116
|
+
ws,
|
|
117
|
+
pending: true,
|
|
118
|
+
pendingControl: [],
|
|
119
|
+
pendingBytes: [],
|
|
120
|
+
pendingTimer: null,
|
|
121
|
+
cols: 0,
|
|
122
|
+
rows: 0,
|
|
123
|
+
windowId,
|
|
124
|
+
coordinator,
|
|
125
|
+
compressMode: null,
|
|
126
|
+
brotliEncoder: null,
|
|
127
|
+
terminalResponder: false,
|
|
128
|
+
};
|
|
129
|
+
coordinator.add(ws);
|
|
130
|
+
managed.clients.add(client);
|
|
131
|
+
this.wsToClient.set(ws, { client, session: managed });
|
|
132
|
+
this.recomputeResize(managed);
|
|
133
|
+
// Seed a joiner with the current effective size when it's entering an
|
|
134
|
+
// already-multi-viewer session whose min its own (possibly wider) report
|
|
135
|
+
// doesn't change — recomputeResize only broadcasts on a change, so without
|
|
136
|
+
// this the new viewer would never learn it's constrained and would render
|
|
137
|
+
// no mask. A fresh spawn (now the lone viewer) has no stored size and is
|
|
138
|
+
// skipped, and a joiner that changes the min is reached by the broadcast.
|
|
139
|
+
if (managed.clients.size > 1 && managed.ptySizeCols !== null && managed.ptySizeRows !== null) {
|
|
140
|
+
this.outputTransport.sendToClient(client, {
|
|
141
|
+
type: "pty-size",
|
|
142
|
+
cols: managed.ptySizeCols,
|
|
143
|
+
rows: managed.ptySizeRows,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Auto-promote a client that never sends {type:"ready"} — a back-compat
|
|
147
|
+
// client (an older bundled terminal, or any plain WS reader) would otherwise
|
|
148
|
+
// stay pending and never receive output. The localterm client sends ready
|
|
149
|
+
// within milliseconds of the session frame; the window is sized to clear a
|
|
150
|
+
// mobile/tailscale RTT (often DERP-relayed) so its {ready} lands first and
|
|
151
|
+
// its scrollback replay still lands before live fan-out. `promote` always
|
|
152
|
+
// sends `replay-end`, so even a slow link that auto-promotes with
|
|
153
|
+
// `replay: false` can't deadlock the client in its replay window.
|
|
154
|
+
client.pendingTimer = setTimeout(() => void this.promote(ws, false), this.pendingPromoteTimeoutMs);
|
|
155
|
+
client.pendingTimer.unref?.();
|
|
156
|
+
this.onSessionActivity();
|
|
157
|
+
return managed;
|
|
158
|
+
}
|
|
159
|
+
// Promote a pending client to live fan-out. Idempotent (a no-op once the
|
|
160
|
+
// client is already live), so the pending timeout and an explicit {ready}
|
|
161
|
+
// can race safely. When `replay` is true the session's scrollback ring
|
|
162
|
+
// buffer is sent as one binary frame first, then the control messages and
|
|
163
|
+
// output bytes buffered while pending flush in order — so a tab switching
|
|
164
|
+
// to this PTY lands on recent output instead of a blank screen, with no
|
|
165
|
+
// live frame interleaving between replay and the buffered fan-out.
|
|
166
|
+
//
|
|
167
|
+
// `replay-end` is sent on EVERY promote (not just `replay: true`): the
|
|
168
|
+
// localterm client opens its suppressed-replay window on the {session}
|
|
169
|
+
// frame — before its {ready} reaches us — so a slow link whose pending
|
|
170
|
+
// timeout auto-promotes with `replay: false` would otherwise never send the
|
|
171
|
+
// marker the client is waiting on, deadlocking it on a blank screen with
|
|
172
|
+
// every output frame buffered client-side. The auto-promote's `replay-end`
|
|
173
|
+
// lets the client flush whatever it buffered (the pending bytes that raced
|
|
174
|
+
// ahead of the marker) and rejoin live fan-out. A client that didn't open the
|
|
175
|
+
// window (a silent reattach, or a back-compat reader) treats it as a no-op.
|
|
176
|
+
async promote(ws, replay, compress = null) {
|
|
177
|
+
const entry = this.wsToClient.get(ws);
|
|
178
|
+
if (!entry)
|
|
179
|
+
return;
|
|
180
|
+
const client = entry.client;
|
|
181
|
+
if (!client.pending)
|
|
182
|
+
return;
|
|
183
|
+
if (client.pendingTimer !== null) {
|
|
184
|
+
clearTimeout(client.pendingTimer);
|
|
185
|
+
client.pendingTimer = null;
|
|
186
|
+
}
|
|
187
|
+
client.compressMode = compress;
|
|
188
|
+
this.ensureTerminalResponder(entry.session, client);
|
|
189
|
+
// Reset the persistent Brotli encoder: a new promote is a fresh attach (a
|
|
190
|
+
// PTY switch or reconnect), so the prior screen's LZ77 context is stale.
|
|
191
|
+
// The first frame of the new stream has no prior context (the per-frame
|
|
192
|
+
// equivalent); subsequent frames compress against it.
|
|
193
|
+
if (client.brotliEncoder !== null) {
|
|
194
|
+
client.brotliEncoder.release();
|
|
195
|
+
client.brotliEncoder = null;
|
|
196
|
+
}
|
|
197
|
+
if (compress === "br-ctx")
|
|
198
|
+
client.brotliEncoder = makeBrotliEncoder(WS_OUTPUT_BROTLI_QUALITY);
|
|
199
|
+
// Tell the client the chosen compress mode BEFORE the scrollback replay so
|
|
200
|
+
// it knows how to parse the compressed replay frames. A back-compat server
|
|
201
|
+
// that doesn't know "br-ctx" never sends this frame, so an old-server +
|
|
202
|
+
// new-client pair degrades to raw (no header) instead of mis-parsing.
|
|
203
|
+
this.sendControl(ws, { type: "compress", mode: compress });
|
|
204
|
+
if (replay) {
|
|
205
|
+
await this.outputTransport.sendScrollback(ws, entry.session, client);
|
|
206
|
+
}
|
|
207
|
+
// Tell the client the replay bytes have all landed so it can write them as
|
|
208
|
+
// one suppressed block (dropping xterm's responses to the stale query
|
|
209
|
+
// requests in the ring buffer). Sent on every promote — even when the
|
|
210
|
+
// snapshot was empty or replay wasn't requested — so the client always
|
|
211
|
+
// exits its suppressed-replay window and never deadlocks on a slow link.
|
|
212
|
+
this.sendControl(ws, { type: "replay-end" });
|
|
213
|
+
for (const payload of client.pendingControl)
|
|
214
|
+
this.sendControl(ws, payload);
|
|
215
|
+
for (const bytes of client.pendingBytes) {
|
|
216
|
+
await this.outputTransport.sendOutputFrame(ws, bytes, client);
|
|
217
|
+
}
|
|
218
|
+
client.pendingControl = [];
|
|
219
|
+
client.pendingBytes = [];
|
|
220
|
+
client.pending = false;
|
|
221
|
+
// Re-push the ambient git-diff summary to the now-live client so a summary
|
|
222
|
+
// pushed while pending (and wiped by the client's cwd-driven null-reset on
|
|
223
|
+
// a cwd change during the pending window) is restored. See
|
|
224
|
+
// GitMetadataCoordinator.replayLastSummary.
|
|
225
|
+
client.coordinator?.replayLastSummary(ws);
|
|
226
|
+
}
|
|
227
|
+
writeInput(ws, data) {
|
|
228
|
+
const entry = this.wsToClient.get(ws);
|
|
229
|
+
if (!entry)
|
|
230
|
+
return;
|
|
231
|
+
// A client sending input is clearly live and wants output. Promote it out
|
|
232
|
+
// of the pending hold without a scrollback replay — a back-compat client
|
|
233
|
+
// that never sends {type:"ready"} still unblocks on its first keystroke.
|
|
234
|
+
// The localterm client sends {type:"ready"} before any input, so this is a
|
|
235
|
+
// no-op for it. Promote flushes any buffered output before the input echoes.
|
|
236
|
+
if (entry.client.pending)
|
|
237
|
+
void this.promote(ws, false);
|
|
238
|
+
// Query replies follow the viewer that most recently drove the PTY.
|
|
239
|
+
this.assignTerminalResponder(entry.session, entry.client);
|
|
240
|
+
entry.session.session.write(data);
|
|
241
|
+
}
|
|
242
|
+
writeTerminalResponse(ws, data) {
|
|
243
|
+
const entry = this.wsToClient.get(ws);
|
|
244
|
+
if (!entry?.client.terminalResponder)
|
|
245
|
+
return;
|
|
246
|
+
this.writeInput(ws, data);
|
|
247
|
+
}
|
|
248
|
+
ensureTerminalResponder(managed, preferredClient) {
|
|
249
|
+
for (const client of managed.clients) {
|
|
250
|
+
if (client.terminalResponder)
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const nextClient = preferredClient ??
|
|
254
|
+
Array.from(managed.clients).find((client) => !client.pending) ??
|
|
255
|
+
managed.clients.values().next().value;
|
|
256
|
+
if (nextClient)
|
|
257
|
+
this.assignTerminalResponder(managed, nextClient);
|
|
258
|
+
}
|
|
259
|
+
assignTerminalResponder(managed, responder) {
|
|
260
|
+
for (const client of managed.clients)
|
|
261
|
+
client.terminalResponder = client === responder;
|
|
262
|
+
}
|
|
263
|
+
resize(ws, cols, rows, pixelWidth, pixelHeight) {
|
|
264
|
+
const entry = this.wsToClient.get(ws);
|
|
265
|
+
if (!entry)
|
|
266
|
+
return;
|
|
267
|
+
entry.client.cols = cols;
|
|
268
|
+
entry.client.rows = rows;
|
|
269
|
+
entry.client.pixelWidth = pixelWidth;
|
|
270
|
+
entry.client.pixelHeight = pixelHeight;
|
|
271
|
+
this.recomputeResize(entry.session);
|
|
272
|
+
}
|
|
273
|
+
// Detach a single client. If this was the last subscriber, arm the
|
|
274
|
+
// no-clients grace timer: the PTY stays alive for SESSION_GRACE_MS so a
|
|
275
|
+
// transient drop or a switch can re-attach, then is reaped if nobody does.
|
|
276
|
+
detach(ws) {
|
|
277
|
+
const entry = this.wsToClient.get(ws);
|
|
278
|
+
if (!entry)
|
|
279
|
+
return;
|
|
280
|
+
this.wsToClient.delete(ws);
|
|
281
|
+
const managed = entry.session;
|
|
282
|
+
const client = entry.client;
|
|
283
|
+
this.releaseClient(client);
|
|
284
|
+
managed.clients.delete(client);
|
|
285
|
+
if (client.terminalResponder)
|
|
286
|
+
this.ensureTerminalResponder(managed);
|
|
287
|
+
this.recomputeResize(managed);
|
|
288
|
+
if (managed.clients.size === 0 && !managed.session.isExited)
|
|
289
|
+
this.startGrace(managed);
|
|
290
|
+
this.onSessionActivity();
|
|
291
|
+
}
|
|
292
|
+
// Fan a control message out to every client currently viewing any session
|
|
293
|
+
// owned by the same identity as `managed`, not just `managed`'s own viewers.
|
|
294
|
+
// Used for notifications so a user who stepped away to another session still
|
|
295
|
+
// gets the ping; owner-scoped so a notification never crosses an identity
|
|
296
|
+
// boundary (a non-operator client can only be attached to an owner-matching
|
|
297
|
+
// session, so matching session.owner === managed.owner is the partition).
|
|
298
|
+
broadcastToOwner(managed, payload) {
|
|
299
|
+
for (const { client, session } of this.wsToClient.values()) {
|
|
300
|
+
if (session.owner === managed.owner)
|
|
301
|
+
this.outputTransport.sendToClient(client, payload);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
recomputeResize(managed) {
|
|
305
|
+
const session = managed.session;
|
|
306
|
+
if (session.isExited)
|
|
307
|
+
return;
|
|
308
|
+
let cols = Infinity;
|
|
309
|
+
let rows = Infinity;
|
|
310
|
+
let single = null;
|
|
311
|
+
let count = 0;
|
|
312
|
+
for (const client of managed.clients) {
|
|
313
|
+
count++;
|
|
314
|
+
single = client;
|
|
315
|
+
if (client.cols > 0 && client.cols < cols)
|
|
316
|
+
cols = client.cols;
|
|
317
|
+
if (client.rows > 0 && client.rows < rows)
|
|
318
|
+
rows = client.rows;
|
|
319
|
+
}
|
|
320
|
+
if (count === 0)
|
|
321
|
+
return;
|
|
322
|
+
if (!Number.isFinite(cols) || !Number.isFinite(rows))
|
|
323
|
+
return;
|
|
324
|
+
if (count === 1 && single?.pixelWidth !== undefined && single?.pixelHeight !== undefined) {
|
|
325
|
+
session.resize(cols, rows, single.pixelWidth, single.pixelHeight);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
session.resize(cols, rows);
|
|
329
|
+
}
|
|
330
|
+
// Keep the capture renderer's grid at the PTY's effective size so a
|
|
331
|
+
// capture-pane reflects the same line wrapping a viewer would see.
|
|
332
|
+
managed.captureRenderer?.resize(cols, rows);
|
|
333
|
+
// The PTY's effective size is the min across attached clients (tmux-style):
|
|
334
|
+
// a narrower peer constrains everyone. Broadcast it on change so each
|
|
335
|
+
// viewer can mask the dead area beyond its own (possibly wider) grid as
|
|
336
|
+
// inactive chrome. A lone viewer is never constrained (its effective size
|
|
337
|
+
// always equals its own), so it's left quiet except for one clear frame when
|
|
338
|
+
// a peer detaches and drops it back to solo — that erases the mask the
|
|
339
|
+
// leaving peer had imposed. A joiner entering an already-constrained
|
|
340
|
+
// session without changing the min is seeded in attach.
|
|
341
|
+
const sizeChanged = managed.ptySizeCols !== cols || managed.ptySizeRows !== rows;
|
|
342
|
+
managed.ptySizeCols = cols;
|
|
343
|
+
managed.ptySizeRows = rows;
|
|
344
|
+
if (count > 1) {
|
|
345
|
+
managed.ptySizeWasMultiViewer = true;
|
|
346
|
+
if (sizeChanged) {
|
|
347
|
+
this.outputTransport.broadcast(managed, { type: "pty-size", cols, rows });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else if (managed.ptySizeWasMultiViewer) {
|
|
351
|
+
managed.ptySizeWasMultiViewer = false;
|
|
352
|
+
this.outputTransport.broadcast(managed, { type: "pty-size", cols, rows });
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
moveClientCoordinators(managed, cwd) {
|
|
356
|
+
for (const client of managed.clients)
|
|
357
|
+
this.moveClientCoordinator(client, cwd);
|
|
358
|
+
}
|
|
359
|
+
moveClientCoordinator(client, cwd) {
|
|
360
|
+
const next = this.coordinatorForCwd(cwd);
|
|
361
|
+
if (client.coordinator === next)
|
|
362
|
+
return;
|
|
363
|
+
if (client.coordinator) {
|
|
364
|
+
client.coordinator.remove(client.ws);
|
|
365
|
+
this.releaseCoordinator(client.coordinator);
|
|
366
|
+
}
|
|
367
|
+
client.coordinator = next;
|
|
368
|
+
next.add(client.ws);
|
|
369
|
+
}
|
|
370
|
+
tearDown(managed) {
|
|
371
|
+
for (const client of managed.clients) {
|
|
372
|
+
if (client.pendingTimer !== null) {
|
|
373
|
+
clearTimeout(client.pendingTimer);
|
|
374
|
+
client.pendingTimer = null;
|
|
375
|
+
}
|
|
376
|
+
client.pendingControl = [];
|
|
377
|
+
client.pendingBytes = [];
|
|
378
|
+
if (client.coordinator) {
|
|
379
|
+
client.coordinator.remove(client.ws);
|
|
380
|
+
this.releaseCoordinator(client.coordinator);
|
|
381
|
+
}
|
|
382
|
+
this.wsToClient.delete(client.ws);
|
|
383
|
+
}
|
|
384
|
+
managed.clients.clear();
|
|
385
|
+
}
|
|
386
|
+
releaseClient(client) {
|
|
387
|
+
if (client.pendingTimer !== null) {
|
|
388
|
+
clearTimeout(client.pendingTimer);
|
|
389
|
+
client.pendingTimer = null;
|
|
390
|
+
}
|
|
391
|
+
if (client.brotliEncoder !== null) {
|
|
392
|
+
client.brotliEncoder.release();
|
|
393
|
+
client.brotliEncoder = null;
|
|
394
|
+
}
|
|
395
|
+
client.pendingControl = [];
|
|
396
|
+
client.pendingBytes = [];
|
|
397
|
+
if (client.coordinator) {
|
|
398
|
+
client.coordinator.remove(client.ws);
|
|
399
|
+
this.releaseCoordinator(client.coordinator);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
dispose() {
|
|
403
|
+
this.coordinatorsByCwd.clear();
|
|
404
|
+
}
|
|
405
|
+
coordinatorForCwd(cwd) {
|
|
406
|
+
const key = path.resolve(cwd);
|
|
407
|
+
let coordinator = this.coordinatorsByCwd.get(key);
|
|
408
|
+
if (!coordinator) {
|
|
409
|
+
coordinator = new GitMetadataCoordinator(key, this.sendControl);
|
|
410
|
+
this.coordinatorsByCwd.set(key, coordinator);
|
|
411
|
+
}
|
|
412
|
+
return coordinator;
|
|
413
|
+
}
|
|
414
|
+
releaseCoordinator(coordinator) {
|
|
415
|
+
if (coordinator.isEmpty)
|
|
416
|
+
this.coordinatorsByCwd.delete(coordinator.cwd);
|
|
417
|
+
}
|
|
418
|
+
// Push a freshly-detected PR to every tab in `cwd` after the
|
|
419
|
+
// /api/git/branches/pr endpoint recomputes it, so a remote state change one
|
|
420
|
+
// tab observed (a merge on GitHub) reaches siblings sharing the directory.
|
|
421
|
+
// Non-creating: a cwd with no subscribers has no coordinator, and allocating
|
|
422
|
+
// one here would orphan it (it never enters the attach/detach release path).
|
|
423
|
+
broadcastGitBranchPr(cwd, pr) {
|
|
424
|
+
this.coordinatorsByCwd.get(path.resolve(cwd))?.broadcastPr(pr);
|
|
425
|
+
}
|
|
426
|
+
// Whether any tab is currently subscribed to the per-cwd coordinator — i.e.
|
|
427
|
+
// there is a live audience for a PR lease refresh. Used to gate the
|
|
428
|
+
// gh-activity refresh so a `gh` invocation in a cwd nobody is viewing never
|
|
429
|
+
// triggers a pointless GitHub API call (mirrors broadcastGitBranchPr's
|
|
430
|
+
// non-creating philosophy).
|
|
431
|
+
hasCoordinatorFor(cwd) {
|
|
432
|
+
return this.coordinatorsByCwd.has(path.resolve(cwd));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=session-client-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-client-hub.js","sourceRoot":"","sources":["../src/session-client-hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ExecOptions, ExecResult, ManagedSession, WaitPredicate, WaitResult } from "./session-manager.js";
|
|
2
|
+
export declare class SessionCommandExecutor {
|
|
3
|
+
capturePane(managed: ManagedSession, lines?: number): Promise<string>;
|
|
4
|
+
waitFor(managed: ManagedSession, predicate: WaitPredicate, timeoutMs: number, idleMs?: number): Promise<WaitResult>;
|
|
5
|
+
findTextInViewport(managed: ManagedSession, needle: string): Promise<{
|
|
6
|
+
col: number;
|
|
7
|
+
row: number;
|
|
8
|
+
} | null>;
|
|
9
|
+
private ensureCaptureRenderer;
|
|
10
|
+
execute(managed: ManagedSession, command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
11
|
+
private buildExecResult;
|
|
12
|
+
private clampInt;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=session-command-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-command-executor.d.ts","sourceRoot":"","sources":["../src/session-command-executor.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACX,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,sBAAsB;IAC3B,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI1E;IAEK,OAAO,CACX,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAwDrB;IAEK,kBAAkB,CACtB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAI9C;YAOa,qBAAqB;IAU7B,OAAO,CACX,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAmGrB;YAEa,eAAe;IAyC7B,OAAO,CAAC,QAAQ;CAGjB"}
|