@thenewlabs/entangle-serve 2.3.0 → 2.5.0
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.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +2 -2
- package/dist/agent.js.map +1 -1
- package/dist/box-renderer.d.ts +21 -0
- package/dist/box-renderer.d.ts.map +1 -1
- package/dist/box-renderer.js +64 -6
- package/dist/box-renderer.js.map +1 -1
- package/dist/host-terminal.d.ts +11 -11
- package/dist/host-terminal.d.ts.map +1 -1
- package/dist/host-terminal.js +189 -51
- package/dist/host-terminal.js.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/multi-session.d.ts +2 -2
- package/dist/multi-session.d.ts.map +1 -1
- package/dist/multi-session.js +81 -18
- package/dist/multi-session.js.map +1 -1
- package/dist/session.d.ts +3 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +5 -3
- package/dist/session.js.map +1 -1
- package/dist/shared-session.d.ts +11 -1
- package/dist/shared-session.d.ts.map +1 -1
- package/dist/shared-session.js +12 -1
- package/dist/shared-session.js.map +1 -1
- package/dist/shared-workspace.d.ts +136 -0
- package/dist/shared-workspace.d.ts.map +1 -0
- package/dist/shared-workspace.js +317 -0
- package/dist/shared-workspace.js.map +1 -0
- package/package.json +4 -4
package/dist/agent.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type CapabilityInfo } from './capability.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SharedWorkspace } from './shared-workspace.js';
|
|
3
3
|
interface AgentOptions {
|
|
4
4
|
serverUrl: string;
|
|
5
5
|
outputMode?: string;
|
|
6
6
|
password?: string;
|
|
7
7
|
pinnedCapability?: CapabilityInfo;
|
|
8
|
-
|
|
8
|
+
sharedWorkspace?: SharedWorkspace;
|
|
9
9
|
onCapabilityReady?: (info: {
|
|
10
10
|
link: string;
|
|
11
11
|
capId: string;
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAGlC,eAAe,CAAC,EAAE,eAAe,CAAC;IAGlC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChF;AAgBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CrE"}
|
package/dist/agent.js
CHANGED
|
@@ -13,7 +13,7 @@ export async function startAgent(options) {
|
|
|
13
13
|
output,
|
|
14
14
|
...(options.outputMode && { outputMode: options.outputMode }),
|
|
15
15
|
...(options.password && { password: options.password }),
|
|
16
|
-
...(options.
|
|
16
|
+
...(options.sharedWorkspace && { sharedWorkspace: options.sharedWorkspace }),
|
|
17
17
|
...(options.onCapabilityReady && { onCapabilityReady: options.onCapabilityReady }),
|
|
18
18
|
};
|
|
19
19
|
output.info('Starting agent');
|
|
@@ -87,7 +87,7 @@ async function connectToServer(state, serverUrl) {
|
|
|
87
87
|
state.output.info(`Invoker connected: socketId=${socketId}, capId=${capId}`);
|
|
88
88
|
// Register synchronously (no await) so the session exists before this
|
|
89
89
|
// invoker's AUTH1 arrives on the next relay message.
|
|
90
|
-
const session = handleInvokerConnection(state.ws, socketId, cap, state.passwordHash, state.
|
|
90
|
+
const session = handleInvokerConnection(state.ws, socketId, cap, state.passwordHash, state.sharedWorkspace);
|
|
91
91
|
relaySessions.set(socketId, session);
|
|
92
92
|
}
|
|
93
93
|
else if (msg.type === 'RELAY_MSG') {
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,iBAAiB,CAAC;AA8BxE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAqB;IACpD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;IACrH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAe;QACxB,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM;QACN,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvD,GAAG,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/box-renderer.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { VtGrid } from './vt-grid.js';
|
|
2
|
+
/** A window as the tab bar needs to see it (index is positional). */
|
|
3
|
+
export interface TabInfo {
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
2
6
|
export declare class BoxRenderer {
|
|
3
7
|
private grid;
|
|
4
8
|
cols: number;
|
|
@@ -18,8 +22,25 @@ export declare class BoxRenderer {
|
|
|
18
22
|
frame(state: {
|
|
19
23
|
viewers: number;
|
|
20
24
|
url: string | undefined;
|
|
25
|
+
windows: readonly TabInfo[];
|
|
26
|
+
activeIndex: number;
|
|
21
27
|
}): string;
|
|
28
|
+
/**
|
|
29
|
+
* Top border doubling as the tab bar:
|
|
30
|
+
*
|
|
31
|
+
* ╔═ ⧉ entangle │ ‹1:shell› 2:logs 3:build │ N viewers ═══╗
|
|
32
|
+
*
|
|
33
|
+
* The active tab is drawn in reverse video. Tabs take priority over the
|
|
34
|
+
* viewer count: the count is only appended if it fits after the brand and
|
|
35
|
+
* tabs, and the tab list itself is truncated with `…` at the terminal width.
|
|
36
|
+
*/
|
|
22
37
|
private topBorder;
|
|
38
|
+
/**
|
|
39
|
+
* Render `│ 1:shell 2:logs …` into at most `maxVis` visible columns, the
|
|
40
|
+
* active tab in reverse video, appending `…` if the list is truncated.
|
|
41
|
+
* Returns the styled string and its visible width (SGR bytes excluded).
|
|
42
|
+
*/
|
|
43
|
+
private renderTabs;
|
|
23
44
|
private bottomBorder;
|
|
24
45
|
/**
|
|
25
46
|
* Pad a border prefix (already including its leading corner) out to the full
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box-renderer.d.ts","sourceRoot":"","sources":["../src/box-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"box-renderer.d.ts","sourceRoot":"","sources":["../src/box-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAyB3C,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,WAAW;IAEpB,OAAO,CAAC,IAAI;IACL,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;gBAFX,IAAI,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAGrB,qEAAqE;IACrE,IAAI,SAAS,IAAI,MAAM,CAAuC;IAE9D,+EAA+E;IAC/E,IAAI,SAAS,IAAI,MAAM,CAAuC;IAE9D,qDAAqD;IACrD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxC;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;QAC5B,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,MAAM;IAwBV;;;;;;;;OAQG;IACH,OAAO,CAAC,SAAS;IAqBjB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,YAAY;IAKpB;;;;OAIG;IACH,OAAO,CAAC,SAAS;CAOlB"}
|
package/dist/box-renderer.js
CHANGED
|
@@ -14,6 +14,10 @@ const BOTTOM_LEFT = '╚';
|
|
|
14
14
|
const BOTTOM_RIGHT = '╝';
|
|
15
15
|
const HORIZONTAL = '═';
|
|
16
16
|
const VERTICAL = '║';
|
|
17
|
+
const SEP = '│';
|
|
18
|
+
/** Reverse-video wrap used to highlight the active window's tab. */
|
|
19
|
+
const REVERSE_ON = '\x1b[7m';
|
|
20
|
+
const REVERSE_OFF = '\x1b[27m';
|
|
17
21
|
export class BoxRenderer {
|
|
18
22
|
grid;
|
|
19
23
|
cols;
|
|
@@ -39,8 +43,8 @@ export class BoxRenderer {
|
|
|
39
43
|
*/
|
|
40
44
|
frame(state) {
|
|
41
45
|
const parts = ['\x1b[?25l\x1b[0m'];
|
|
42
|
-
// Title bar.
|
|
43
|
-
parts.push('\x1b[1;1H', this.topBorder(state.viewers));
|
|
46
|
+
// Title/tab bar.
|
|
47
|
+
parts.push('\x1b[1;1H', this.topBorder(state.windows, state.activeIndex, state.viewers));
|
|
44
48
|
// Interior rows: rail + shell row + rail.
|
|
45
49
|
const gridRows = this.grid.renderRows();
|
|
46
50
|
for (let i = 0; i < this.innerRows; i++) {
|
|
@@ -55,10 +59,64 @@ export class BoxRenderer {
|
|
|
55
59
|
parts.push(`\x1b[${cy};${cx}H`, '\x1b[?25h');
|
|
56
60
|
return parts.join('');
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Top border doubling as the tab bar:
|
|
64
|
+
*
|
|
65
|
+
* ╔═ ⧉ entangle │ ‹1:shell› 2:logs 3:build │ N viewers ═══╗
|
|
66
|
+
*
|
|
67
|
+
* The active tab is drawn in reverse video. Tabs take priority over the
|
|
68
|
+
* viewer count: the count is only appended if it fits after the brand and
|
|
69
|
+
* tabs, and the tab list itself is truncated with `…` at the terminal width.
|
|
70
|
+
*/
|
|
71
|
+
topBorder(windows, activeIndex, viewers) {
|
|
72
|
+
const budget = Math.max(0, this.cols - 1); // reserve the end corner
|
|
73
|
+
const brand = `${TOP_LEFT}${HORIZONTAL} ⧉ entangle `;
|
|
74
|
+
const viewerSeg = `${SEP} ${viewers} viewer${viewers === 1 ? '' : 's'} `;
|
|
75
|
+
let styled = brand;
|
|
76
|
+
let vis = brand.length;
|
|
77
|
+
// Keep the viewer count only if the tabs still get a usable slice.
|
|
78
|
+
const showViewers = budget - vis - viewerSeg.length >= 6;
|
|
79
|
+
const tabsBudget = Math.max(0, budget - vis - (showViewers ? viewerSeg.length : 0));
|
|
80
|
+
const tabs = this.renderTabs(windows, activeIndex, tabsBudget);
|
|
81
|
+
styled += tabs.styled;
|
|
82
|
+
vis += tabs.vis;
|
|
83
|
+
if (showViewers) {
|
|
84
|
+
styled += viewerSeg;
|
|
85
|
+
vis += viewerSeg.length;
|
|
86
|
+
}
|
|
87
|
+
if (vis < budget)
|
|
88
|
+
styled += HORIZONTAL.repeat(budget - vis);
|
|
89
|
+
return styled + TOP_RIGHT;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Render `│ 1:shell 2:logs …` into at most `maxVis` visible columns, the
|
|
93
|
+
* active tab in reverse video, appending `…` if the list is truncated.
|
|
94
|
+
* Returns the styled string and its visible width (SGR bytes excluded).
|
|
95
|
+
*/
|
|
96
|
+
renderTabs(windows, activeIndex, maxVis) {
|
|
97
|
+
if (maxVis <= 2 || windows.length === 0)
|
|
98
|
+
return { styled: '', vis: 0 };
|
|
99
|
+
let styled = `${SEP}`;
|
|
100
|
+
let vis = 1;
|
|
101
|
+
for (let i = 0; i < windows.length; i++) {
|
|
102
|
+
const title = windows[i].title.replace(/[\x00-\x1f\x7f]/g, '');
|
|
103
|
+
const token = ` ${i + 1}:${title} `;
|
|
104
|
+
if (vis + token.length > maxVis) {
|
|
105
|
+
// Not enough room: fit what we can, then an ellipsis, and stop.
|
|
106
|
+
const remain = maxVis - vis - 1;
|
|
107
|
+
if (remain > 0) {
|
|
108
|
+
const slice = token.slice(0, remain);
|
|
109
|
+
styled += i === activeIndex ? `${REVERSE_ON}${slice}${REVERSE_OFF}` : slice;
|
|
110
|
+
vis += remain;
|
|
111
|
+
}
|
|
112
|
+
styled += '…';
|
|
113
|
+
vis += 1;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
styled += i === activeIndex ? `${REVERSE_ON}${token}${REVERSE_OFF}` : token;
|
|
117
|
+
vis += token.length;
|
|
118
|
+
}
|
|
119
|
+
return { styled, vis };
|
|
62
120
|
}
|
|
63
121
|
bottomBorder(url) {
|
|
64
122
|
const shown = url ?? 'connecting…';
|
package/dist/box-renderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box-renderer.js","sourceRoot":"","sources":["../src/box-renderer.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,QAAQ,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"box-renderer.js","sourceRoot":"","sources":["../src/box-renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/host-terminal.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { OutputHandler } from '@thenewlabs/entangle-utils';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SharedWorkspace } from './shared-workspace.js';
|
|
3
3
|
/**
|
|
4
4
|
* Handle returned by {@link attachHostTerminal}. The session URL is only known
|
|
5
5
|
* once the relay assigns the capability, so index.ts feeds it in later via
|
|
6
|
-
* {@link HostTerminalHandle.setUrl}; until then the
|
|
7
|
-
* "connecting…"
|
|
6
|
+
* {@link HostTerminalHandle.setUrl}; until then the host shows a brief
|
|
7
|
+
* "connecting…" screen and only goes live once the URL arrives.
|
|
8
8
|
*/
|
|
9
9
|
export interface HostTerminalHandle {
|
|
10
10
|
setUrl(link: string): void;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Wire the host's own terminal to the shared
|
|
13
|
+
* Wire the host's own terminal to the shared workspace.
|
|
14
14
|
*
|
|
15
|
-
* On a real, big-enough terminal the host sees their shell rendered
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* back to raw pass-through.
|
|
15
|
+
* On a real, big-enough terminal the host sees their shell rendered RAW at full
|
|
16
|
+
* width, using rows 1..(rows-1), with a blue tmux-style status bar pinned to the
|
|
17
|
+
* bottom row. The shell is authoritative-sized to (cols, rows-1) and a scroll
|
|
18
|
+
* region keeps its scrolling clear of the bar; because output is passed through
|
|
19
|
+
* byte-for-byte (no VtGrid), resizes stay clean. Elsewhere (too small, or not a
|
|
20
|
+
* TTY) it falls back to raw pass-through.
|
|
21
21
|
*/
|
|
22
|
-
export declare function attachHostTerminal(shared:
|
|
22
|
+
export declare function attachHostTerminal(shared: SharedWorkspace, output: OutputHandler): HostTerminalHandle;
|
|
23
23
|
//# sourceMappingURL=host-terminal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-terminal.d.ts","sourceRoot":"","sources":["../src/host-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"host-terminal.d.ts","sourceRoot":"","sources":["../src/host-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAS3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAkB7D;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,GAAG,kBAAkB,CAYrG"}
|
package/dist/host-terminal.js
CHANGED
|
@@ -1,78 +1,187 @@
|
|
|
1
|
-
|
|
2
|
-
import { BoxRenderer } from './box-renderer.js';
|
|
3
|
-
/** Minimum terminal size that can hold the session frame with a usable interior. */
|
|
1
|
+
/** Minimum terminal size that can hold the shell plus a bottom status bar. */
|
|
4
2
|
const MIN_COLS = 20;
|
|
5
3
|
const MIN_ROWS = 6;
|
|
6
|
-
/** Repaint cadence: coalesce shell output into ~30ms frames
|
|
4
|
+
/** Repaint cadence for the status bar: coalesce shell output into ~30ms frames. */
|
|
7
5
|
const FRAME_MS = 30;
|
|
6
|
+
/** Host window-management prefix (Ctrl-B), tmux-style. */
|
|
7
|
+
const PREFIX = 0x02;
|
|
8
|
+
/** Status-bar palette (tmux-style blue). */
|
|
9
|
+
const BAR_BG = '\x1b[48;5;25m'; // base blue background
|
|
10
|
+
const BAR_ACTIVE_BG = '\x1b[48;5;33m'; // brighter blue for the active tab
|
|
11
|
+
const BAR_FG = '\x1b[97m'; // bright white text
|
|
12
|
+
const RESET = '\x1b[0m';
|
|
8
13
|
/**
|
|
9
|
-
* Wire the host's own terminal to the shared
|
|
14
|
+
* Wire the host's own terminal to the shared workspace.
|
|
10
15
|
*
|
|
11
|
-
* On a real, big-enough terminal the host sees their shell rendered
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* back to raw pass-through.
|
|
16
|
+
* On a real, big-enough terminal the host sees their shell rendered RAW at full
|
|
17
|
+
* width, using rows 1..(rows-1), with a blue tmux-style status bar pinned to the
|
|
18
|
+
* bottom row. The shell is authoritative-sized to (cols, rows-1) and a scroll
|
|
19
|
+
* region keeps its scrolling clear of the bar; because output is passed through
|
|
20
|
+
* byte-for-byte (no VtGrid), resizes stay clean. Elsewhere (too small, or not a
|
|
21
|
+
* TTY) it falls back to raw pass-through.
|
|
17
22
|
*/
|
|
18
23
|
export function attachHostTerminal(shared, output) {
|
|
19
24
|
const stdout = process.stdout;
|
|
20
25
|
const stdin = process.stdin;
|
|
21
26
|
const cols = stdout.columns || 0;
|
|
22
27
|
const rows = stdout.rows || 0;
|
|
23
|
-
const
|
|
24
|
-
return
|
|
25
|
-
?
|
|
28
|
+
const barCapable = !!stdout.isTTY && !!stdin.isTTY && cols >= MIN_COLS && rows >= MIN_ROWS;
|
|
29
|
+
return barCapable
|
|
30
|
+
? attachBarTerminal(shared, output, cols, rows)
|
|
26
31
|
: attachRawTerminal(shared, output);
|
|
27
32
|
}
|
|
28
|
-
/**
|
|
29
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Blue-bottom-bar UI (the normal interactive host experience).
|
|
35
|
+
*
|
|
36
|
+
* Launch sequence: clear + "connecting…" on attach; then on setUrl clear again,
|
|
37
|
+
* print an info banner (brand, share URL, key hint) at the top, set the scroll
|
|
38
|
+
* region, size the shell to rows-1, paint its current screen from the replay,
|
|
39
|
+
* draw the bar, and go live (raw pass-through + status bar).
|
|
40
|
+
*/
|
|
41
|
+
function attachBarTerminal(shared, output, initialCols, initialRows) {
|
|
30
42
|
const stdout = process.stdout;
|
|
31
43
|
const stdin = process.stdin;
|
|
32
44
|
const write = (s) => { try {
|
|
33
45
|
stdout.write(s);
|
|
34
46
|
}
|
|
35
47
|
catch { } };
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
grid.write(Buffer.from(initial).toString('utf8'));
|
|
44
|
-
let url;
|
|
48
|
+
const writeRaw = (b) => { try {
|
|
49
|
+
stdout.write(Buffer.from(b));
|
|
50
|
+
}
|
|
51
|
+
catch { } };
|
|
52
|
+
let cols = initialCols;
|
|
53
|
+
let rows = initialRows;
|
|
54
|
+
let live = false; // true once the URL is known and we're in pass-through
|
|
45
55
|
let viewers = shared.viewerCount();
|
|
46
|
-
let
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
let barDirty = false;
|
|
57
|
+
// Local mirror of the workspace's window set, kept in sync via onWindowState
|
|
58
|
+
// and rendered as the tab row of the bar. Seeded with the current state.
|
|
59
|
+
const initialState = shared.windowState();
|
|
60
|
+
let windows = initialState.windows;
|
|
61
|
+
let activeIndex = initialState.activeIndex;
|
|
62
|
+
/**
|
|
63
|
+
* Compose the status bar for the bottom row: ` ⧉ entangle ` then 1-based
|
|
64
|
+
* window tabs (the active one in brighter blue) and a right-aligned viewer
|
|
65
|
+
* count, all on blue and padded/truncated to exactly `cols` visible columns.
|
|
66
|
+
*/
|
|
67
|
+
const buildBar = () => {
|
|
68
|
+
const segs = [
|
|
69
|
+
{ text: ' ⧉ entangle ', active: false },
|
|
70
|
+
];
|
|
71
|
+
for (let i = 0; i < windows.length; i++) {
|
|
72
|
+
const title = (windows[i].title || '').replace(/[\x00-\x1f\x7f]/g, '');
|
|
73
|
+
segs.push({ text: ` ${i + 1}:${title} `, active: i === activeIndex });
|
|
74
|
+
}
|
|
75
|
+
const viewerSeg = ` ${viewers} viewer${viewers === 1 ? '' : 's'} `;
|
|
76
|
+
// Reserve room on the right for the viewer count when it fits.
|
|
77
|
+
const showViewer = viewerSeg.length + 1 <= cols;
|
|
78
|
+
const leftBudget = showViewer ? cols - viewerSeg.length : cols;
|
|
79
|
+
// Emit the left segments up to leftBudget visible columns, truncating the
|
|
80
|
+
// last one that overflows (each active segment is wrapped in its own bg).
|
|
81
|
+
let left = '';
|
|
82
|
+
let leftVis = 0;
|
|
83
|
+
for (const s of segs) {
|
|
84
|
+
if (leftVis >= leftBudget)
|
|
85
|
+
break;
|
|
86
|
+
const room = leftBudget - leftVis;
|
|
87
|
+
const text = s.text.length > room ? s.text.slice(0, room) : s.text;
|
|
88
|
+
left += s.active ? `${BAR_ACTIVE_BG}${text}${BAR_BG}` : text;
|
|
89
|
+
leftVis += text.length;
|
|
55
90
|
}
|
|
56
|
-
|
|
91
|
+
const fill = ' '.repeat(Math.max(0, cols - leftVis - (showViewer ? viewerSeg.length : 0)));
|
|
92
|
+
const right = showViewer ? viewerSeg : '';
|
|
93
|
+
return `${BAR_BG}${BAR_FG}${left}${fill}${right}${RESET}`;
|
|
94
|
+
};
|
|
95
|
+
// Draw the bar on the bottom row without disturbing the shell: save the cursor
|
|
96
|
+
// and its attributes (DECSC), jump to the last row, clear it, paint the bar,
|
|
97
|
+
// then restore (DECRC). No-op until live so the connecting screen stays clean.
|
|
98
|
+
const drawBar = () => {
|
|
99
|
+
if (!live)
|
|
100
|
+
return;
|
|
101
|
+
barDirty = false;
|
|
102
|
+
write(`\x1b7\x1b[${rows};1H\x1b[2K${buildBar()}\x1b8`);
|
|
57
103
|
};
|
|
58
|
-
// Coalesce shell output
|
|
59
|
-
|
|
104
|
+
// Coalesce shell output into throttled bar redraws so a full-screen app or a
|
|
105
|
+
// `clear` can't leave the bar blank.
|
|
106
|
+
const timer = setInterval(() => { if (barDirty)
|
|
107
|
+
drawBar(); }, FRAME_MS);
|
|
60
108
|
timer.unref?.();
|
|
61
|
-
shared.onHostData((chunk) => {
|
|
62
|
-
|
|
109
|
+
shared.onHostData((chunk) => {
|
|
110
|
+
if (!live)
|
|
111
|
+
return; // pre-live output is captured in the replay; painted on go-live
|
|
112
|
+
writeRaw(chunk);
|
|
113
|
+
barDirty = true;
|
|
114
|
+
});
|
|
115
|
+
shared.onViewersChange((n) => { viewers = n; drawBar(); });
|
|
116
|
+
shared.onWindowState((state) => {
|
|
117
|
+
windows = state.windows;
|
|
118
|
+
activeIndex = state.activeIndex;
|
|
119
|
+
drawBar();
|
|
120
|
+
});
|
|
63
121
|
const wasRaw = !!stdin.isRaw;
|
|
64
122
|
stdin.setRawMode(true);
|
|
65
123
|
stdin.resume();
|
|
66
|
-
|
|
124
|
+
// Window-management commands after a Ctrl-B prefix. Unknown keys are swallowed.
|
|
125
|
+
const runCommand = (byte) => {
|
|
126
|
+
const ch = String.fromCharCode(byte);
|
|
127
|
+
if (ch === 'c')
|
|
128
|
+
shared.newWindow();
|
|
129
|
+
else if (ch === 'n')
|
|
130
|
+
shared.nextWindow();
|
|
131
|
+
else if (ch === 'p')
|
|
132
|
+
shared.prevWindow();
|
|
133
|
+
else if (ch === 'x')
|
|
134
|
+
shared.closeWindow(activeIndex);
|
|
135
|
+
else if (ch >= '0' && ch <= '9') {
|
|
136
|
+
// Tabs are labelled 1-based ("1:shell" = index 0), so digit 1..9 selects
|
|
137
|
+
// window 0..8 and 0 selects window 9 (ignored if out of range).
|
|
138
|
+
const digit = byte - 0x30;
|
|
139
|
+
shared.selectWindow(digit === 0 ? 9 : digit - 1);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
// Ctrl-B prefix state machine: a lone Ctrl-B arms the prefix; the next byte is
|
|
143
|
+
// a command (Ctrl-B again = a literal Ctrl-B to the active window). All other
|
|
144
|
+
// bytes forward to the active window, flushed around each prefix boundary so
|
|
145
|
+
// ordering across a window switch is preserved.
|
|
146
|
+
let pendingPrefix = false;
|
|
147
|
+
const onInput = (d) => {
|
|
148
|
+
let start = 0;
|
|
149
|
+
for (let i = 0; i < d.length; i++) {
|
|
150
|
+
const byte = d[i];
|
|
151
|
+
if (pendingPrefix) {
|
|
152
|
+
pendingPrefix = false;
|
|
153
|
+
if (byte === PREFIX)
|
|
154
|
+
shared.write(new Uint8Array([PREFIX]));
|
|
155
|
+
else
|
|
156
|
+
runCommand(byte);
|
|
157
|
+
start = i + 1;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (byte === PREFIX) {
|
|
161
|
+
if (i > start)
|
|
162
|
+
shared.write(new Uint8Array(d.subarray(start, i)));
|
|
163
|
+
pendingPrefix = true;
|
|
164
|
+
start = i + 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (d.length > start)
|
|
168
|
+
shared.write(new Uint8Array(d.subarray(start)));
|
|
169
|
+
};
|
|
67
170
|
stdin.on('data', onInput);
|
|
171
|
+
// Clean resize: drop the scroll region, clear, re-arm the region one row short,
|
|
172
|
+
// resize the shell (which SIGWINCHes it into redrawing itself), then repaint
|
|
173
|
+
// the bar. No banner reprint — the shell's own redraw fills the screen.
|
|
68
174
|
const onResize = () => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
175
|
+
cols = stdout.columns || cols;
|
|
176
|
+
rows = stdout.rows || rows;
|
|
177
|
+
if (!live)
|
|
178
|
+
return;
|
|
179
|
+
const shellRows = Math.max(1, rows - 1);
|
|
180
|
+
write('\x1b[r');
|
|
181
|
+
write('\x1b[2J\x1b[H');
|
|
182
|
+
write(`\x1b[1;${shellRows}r`);
|
|
183
|
+
shared.resize(cols, shellRows);
|
|
184
|
+
drawBar();
|
|
76
185
|
};
|
|
77
186
|
stdout.on('resize', onResize);
|
|
78
187
|
let restored = false;
|
|
@@ -83,6 +192,7 @@ function attachBoxTerminal(shared, output, cols, rows) {
|
|
|
83
192
|
clearInterval(timer);
|
|
84
193
|
stdin.removeListener('data', onInput);
|
|
85
194
|
stdout.removeListener('resize', onResize);
|
|
195
|
+
write('\x1b[r'); // reset scroll region
|
|
86
196
|
write('\x1b[?25h'); // show cursor
|
|
87
197
|
if (stdin.isTTY) {
|
|
88
198
|
try {
|
|
@@ -100,13 +210,41 @@ function attachBoxTerminal(shared, output, cols, rows) {
|
|
|
100
210
|
});
|
|
101
211
|
process.on('exit', restore);
|
|
102
212
|
process.on('SIGINT', () => { restore(); process.exit(130); });
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
213
|
+
// Info banner shown at the top when the session goes live. `\r\n` because raw
|
|
214
|
+
// mode does not translate a bare `\n` into a carriage return.
|
|
215
|
+
const writeBanner = (link) => {
|
|
216
|
+
write(`${BAR_FG}⧉ entangle${RESET} — live shared session\r\n` +
|
|
217
|
+
`Share this live session:\r\n` +
|
|
218
|
+
` ${BAR_FG}${link}${RESET}\r\n` +
|
|
219
|
+
`Windows: Ctrl-B then c=new n/p=prev/next 1-9=select x=close\r\n`);
|
|
220
|
+
};
|
|
221
|
+
// Connecting screen until the relay hands us the capability URL.
|
|
222
|
+
write('\x1b[2J\x1b[H');
|
|
223
|
+
write(`${BAR_FG}⧉ entangle — connecting…${RESET}`);
|
|
224
|
+
return {
|
|
225
|
+
setUrl(link) {
|
|
226
|
+
if (live) {
|
|
227
|
+
barDirty = true;
|
|
228
|
+
return;
|
|
229
|
+
} // URL refresh after we're already live
|
|
230
|
+
cols = stdout.columns || cols;
|
|
231
|
+
rows = stdout.rows || rows;
|
|
232
|
+
const shellRows = Math.max(1, rows - 1);
|
|
233
|
+
write('\x1b[2J\x1b[H');
|
|
234
|
+
writeBanner(link);
|
|
235
|
+
write(`\x1b[1;${shellRows}r`); // reserve the bottom row for the bar
|
|
236
|
+
shared.resize(cols, shellRows); // shell is authoritative-sized to rows-1
|
|
237
|
+
const replay = shared.getReplay(); // paint the shell's current screen below the banner
|
|
238
|
+
if (replay.length > 0)
|
|
239
|
+
writeRaw(replay);
|
|
240
|
+
live = true;
|
|
241
|
+
drawBar();
|
|
242
|
+
},
|
|
243
|
+
};
|
|
106
244
|
}
|
|
107
245
|
/**
|
|
108
246
|
* Raw pass-through: mirror the shell byte-for-byte and forward keystrokes, with
|
|
109
|
-
* no
|
|
247
|
+
* no status bar. Used when the terminal is too small for a bar (or not a TTY).
|
|
110
248
|
*/
|
|
111
249
|
function attachRawTerminal(shared, output) {
|
|
112
250
|
const stdin = process.stdin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-terminal.js","sourceRoot":"","sources":["../src/host-terminal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host-terminal.js","sourceRoot":"","sources":["../src/host-terminal.ts"],"names":[],"mappings":"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"}
|