dmux 2.2.1 → 3.0.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/DmuxApp.d.ts.map +1 -1
- package/dist/DmuxApp.js +412 -179
- package/dist/DmuxApp.js.map +1 -1
- package/dist/MergePane.d.ts.map +1 -1
- package/dist/MergePane.js +4 -6
- package/dist/MergePane.js.map +1 -1
- package/dist/PaneAnalyzer.d.ts +45 -0
- package/dist/PaneAnalyzer.d.ts.map +1 -0
- package/dist/PaneAnalyzer.js +278 -0
- package/dist/PaneAnalyzer.js.map +1 -0
- package/dist/_plugin-vue_export-helper.css +1 -0
- package/dist/actions/index.d.ts +19 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +54 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/paneActions.d.ts +45 -0
- package/dist/actions/paneActions.d.ts.map +1 -0
- package/dist/actions/paneActions.js +932 -0
- package/dist/actions/paneActions.js.map +1 -0
- package/dist/actions/types.d.ts +101 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +129 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/adapters/apiActionHandler.d.ts +64 -0
- package/dist/adapters/apiActionHandler.d.ts.map +1 -0
- package/dist/adapters/apiActionHandler.js +170 -0
- package/dist/adapters/apiActionHandler.js.map +1 -0
- package/dist/adapters/tuiActionHandler.d.ts +57 -0
- package/dist/adapters/tuiActionHandler.d.ts.map +1 -0
- package/dist/adapters/tuiActionHandler.js +152 -0
- package/dist/adapters/tuiActionHandler.js.map +1 -0
- package/dist/chunks/_plugin-vue_export-helper-Cvoq67hi.js +28 -0
- package/dist/components/ActionChoiceDialog.d.ts +16 -0
- package/dist/components/ActionChoiceDialog.d.ts.map +1 -0
- package/dist/components/ActionChoiceDialog.js +29 -0
- package/dist/components/ActionChoiceDialog.js.map +1 -0
- package/dist/components/ActionConfirmDialog.d.ts +16 -0
- package/dist/components/ActionConfirmDialog.d.ts.map +1 -0
- package/dist/components/ActionConfirmDialog.js +31 -0
- package/dist/components/ActionConfirmDialog.js.map +1 -0
- package/dist/components/ActionInputDialog.d.ts +16 -0
- package/dist/components/ActionInputDialog.d.ts.map +1 -0
- package/dist/components/ActionInputDialog.js +49 -0
- package/dist/components/ActionInputDialog.js.map +1 -0
- package/dist/components/ActionProgressDialog.d.ts +13 -0
- package/dist/components/ActionProgressDialog.d.ts.map +1 -0
- package/dist/components/ActionProgressDialog.js +20 -0
- package/dist/components/ActionProgressDialog.js.map +1 -0
- package/dist/components/FooterHelp.d.ts +2 -0
- package/dist/components/FooterHelp.d.ts.map +1 -1
- package/dist/components/FooterHelp.js +9 -2
- package/dist/components/FooterHelp.js.map +1 -1
- package/dist/components/KebabMenu.d.ts +10 -0
- package/dist/components/KebabMenu.d.ts.map +1 -0
- package/dist/components/KebabMenu.js +18 -0
- package/dist/components/KebabMenu.js.map +1 -0
- package/dist/components/LoadingIndicator.d.ts.map +1 -1
- package/dist/components/LoadingIndicator.js +5 -5
- package/dist/components/LoadingIndicator.js.map +1 -1
- package/dist/components/PaneCard.d.ts +1 -0
- package/dist/components/PaneCard.d.ts.map +1 -1
- package/dist/components/PaneCard.js +21 -20
- package/dist/components/PaneCard.js.map +1 -1
- package/dist/components/PanesGrid.d.ts +1 -0
- package/dist/components/PanesGrid.d.ts.map +1 -1
- package/dist/components/PanesGrid.js +5 -4
- package/dist/components/PanesGrid.js.map +1 -1
- package/dist/components/QRCode.d.ts +7 -0
- package/dist/components/QRCode.d.ts.map +1 -0
- package/dist/components/QRCode.js +19 -0
- package/dist/components/QRCode.js.map +1 -0
- package/dist/components/Spinner.d.ts +10 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +15 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/dashboard.html +14 -0
- package/dist/dashboard.js +2 -0
- package/dist/hooks/useActionSystem.d.ts +31 -0
- package/dist/hooks/useActionSystem.d.ts.map +1 -0
- package/dist/hooks/useActionSystem.js +95 -0
- package/dist/hooks/useActionSystem.js.map +1 -0
- package/dist/hooks/useAgentStatus.d.ts +4 -3
- package/dist/hooks/useAgentStatus.d.ts.map +1 -1
- package/dist/hooks/useAgentStatus.js +45 -194
- package/dist/hooks/useAgentStatus.js.map +1 -1
- package/dist/hooks/usePaneCreation.d.ts +2 -1
- package/dist/hooks/usePaneCreation.d.ts.map +1 -1
- package/dist/hooks/usePaneCreation.js +46 -100
- package/dist/hooks/usePaneCreation.js.map +1 -1
- package/dist/hooks/usePanes.d.ts.map +1 -1
- package/dist/hooks/usePanes.js +5 -3
- package/dist/hooks/usePanes.js.map +1 -1
- package/dist/hooks/useTerminalWidth.d.ts.map +1 -1
- package/dist/hooks/useTerminalWidth.js +18 -1
- package/dist/hooks/useTerminalWidth.js.map +1 -1
- package/dist/hooks/useWorktreeActions.d.ts.map +1 -1
- package/dist/hooks/useWorktreeActions.js +4 -0
- package/dist/hooks/useWorktreeActions.js.map +1 -1
- package/dist/index.js +43 -3
- package/dist/index.js.map +1 -1
- package/dist/server/actionsApi.d.ts +37 -0
- package/dist/server/actionsApi.d.ts.map +1 -0
- package/dist/server/actionsApi.js +256 -0
- package/dist/server/actionsApi.js.map +1 -0
- package/dist/server/embedded-assets.d.ts +13 -0
- package/dist/server/embedded-assets.d.ts.map +1 -0
- package/dist/server/embedded-assets.js +5012 -0
- package/dist/server/embedded-assets.js.map +1 -0
- package/dist/server/index.d.ts +21 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +99 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes.d.ts +3 -0
- package/dist/server/routes.d.ts.map +1 -0
- package/dist/server/routes.js +672 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/server/static.d.ts +6 -0
- package/dist/server/static.d.ts.map +1 -0
- package/dist/server/static.js +3040 -0
- package/dist/server/static.js.map +1 -0
- package/dist/services/ConfigWatcher.d.ts +20 -0
- package/dist/services/ConfigWatcher.d.ts.map +1 -0
- package/dist/services/ConfigWatcher.js +75 -0
- package/dist/services/ConfigWatcher.js.map +1 -0
- package/dist/services/PaneWorkerManager.d.ts +69 -0
- package/dist/services/PaneWorkerManager.d.ts.map +1 -0
- package/dist/services/PaneWorkerManager.js +272 -0
- package/dist/services/PaneWorkerManager.js.map +1 -0
- package/dist/services/StatusDetector.d.ts +87 -0
- package/dist/services/StatusDetector.d.ts.map +1 -0
- package/dist/services/StatusDetector.js +387 -0
- package/dist/services/StatusDetector.js.map +1 -0
- package/dist/services/TerminalDiffer.d.ts +85 -0
- package/dist/services/TerminalDiffer.d.ts.map +1 -0
- package/dist/services/TerminalDiffer.js +499 -0
- package/dist/services/TerminalDiffer.js.map +1 -0
- package/dist/services/TerminalStreamer.d.ts +80 -0
- package/dist/services/TerminalStreamer.d.ts.map +1 -0
- package/dist/services/TerminalStreamer.js +490 -0
- package/dist/services/TerminalStreamer.js.map +1 -0
- package/dist/services/TunnelService.d.ts +9 -0
- package/dist/services/TunnelService.d.ts.map +1 -0
- package/dist/services/TunnelService.js +34 -0
- package/dist/services/TunnelService.js.map +1 -0
- package/dist/services/WorkerMessageBus.d.ts +48 -0
- package/dist/services/WorkerMessageBus.d.ts.map +1 -0
- package/dist/services/WorkerMessageBus.js +120 -0
- package/dist/services/WorkerMessageBus.js.map +1 -0
- package/dist/shared/StateManager.d.ts +34 -0
- package/dist/shared/StateManager.d.ts.map +1 -0
- package/dist/shared/StateManager.js +108 -0
- package/dist/shared/StateManager.js.map +1 -0
- package/dist/shared/StreamProtocol.d.ts +75 -0
- package/dist/shared/StreamProtocol.d.ts.map +1 -0
- package/dist/shared/StreamProtocol.js +37 -0
- package/dist/shared/StreamProtocol.js.map +1 -0
- package/dist/terminal.html +17 -0
- package/dist/terminal.js +3 -0
- package/dist/types.d.ts +21 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/agentDetection.d.ts +18 -0
- package/dist/utils/agentDetection.d.ts.map +1 -0
- package/dist/utils/agentDetection.js +73 -0
- package/dist/utils/agentDetection.js.map +1 -0
- package/dist/utils/aiMerge.d.ts +35 -0
- package/dist/utils/aiMerge.d.ts.map +1 -0
- package/dist/utils/aiMerge.js +298 -0
- package/dist/utils/aiMerge.js.map +1 -0
- package/dist/utils/conflictResolutionPane.d.ts +19 -0
- package/dist/utils/conflictResolutionPane.d.ts.map +1 -0
- package/dist/utils/conflictResolutionPane.js +214 -0
- package/dist/utils/conflictResolutionPane.js.map +1 -0
- package/dist/utils/mergeExecution.d.ts +52 -0
- package/dist/utils/mergeExecution.d.ts.map +1 -0
- package/dist/utils/mergeExecution.js +192 -0
- package/dist/utils/mergeExecution.js.map +1 -0
- package/dist/utils/mergeValidation.d.ts +67 -0
- package/dist/utils/mergeValidation.d.ts.map +1 -0
- package/dist/utils/mergeValidation.js +213 -0
- package/dist/utils/mergeValidation.js.map +1 -0
- package/dist/utils/paneCreation.d.ts +17 -0
- package/dist/utils/paneCreation.d.ts.map +1 -0
- package/dist/utils/paneCreation.js +274 -0
- package/dist/utils/paneCreation.js.map +1 -0
- package/dist/utils/port.d.ts +5 -0
- package/dist/utils/port.d.ts.map +1 -0
- package/dist/utils/port.js +54 -0
- package/dist/utils/port.js.map +1 -0
- package/dist/workers/PaneWorker.d.ts +2 -0
- package/dist/workers/PaneWorker.d.ts.map +1 -0
- package/dist/workers/PaneWorker.js +362 -0
- package/dist/workers/PaneWorker.js.map +1 -0
- package/dist/workers/WorkerMessages.d.ts +36 -0
- package/dist/workers/WorkerMessages.d.ts.map +1 -0
- package/dist/workers/WorkerMessages.js +9 -0
- package/dist/workers/WorkerMessages.js.map +1 -0
- package/package.json +19 -5
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { execSync, spawn } from 'child_process';
|
|
3
|
+
import { existsSync, unlinkSync } from 'fs';
|
|
4
|
+
import { StringDecoder } from 'string_decoder';
|
|
5
|
+
import { formatStreamMessage } from '../shared/StreamProtocol.js';
|
|
6
|
+
/**
|
|
7
|
+
* Manages real-time streaming of tmux panes to browser clients
|
|
8
|
+
* Uses Server-Sent Events for efficient one-way data flow
|
|
9
|
+
*/
|
|
10
|
+
export class TerminalStreamer extends EventEmitter {
|
|
11
|
+
streams = new Map();
|
|
12
|
+
isShuttingDown = false;
|
|
13
|
+
/**
|
|
14
|
+
* Start streaming a pane to a client
|
|
15
|
+
*/
|
|
16
|
+
async startStream(paneId, tmuxPaneId, client) {
|
|
17
|
+
if (this.isShuttingDown)
|
|
18
|
+
return;
|
|
19
|
+
// Get or create stream info for this pane
|
|
20
|
+
let stream = this.streams.get(paneId);
|
|
21
|
+
if (!stream) {
|
|
22
|
+
stream = await this.initializeStream(paneId, tmuxPaneId);
|
|
23
|
+
this.streams.set(paneId, stream);
|
|
24
|
+
}
|
|
25
|
+
// Add client to stream
|
|
26
|
+
stream.clients.add(client);
|
|
27
|
+
// Send initial state to new client
|
|
28
|
+
await this.sendInitialState(stream, client);
|
|
29
|
+
// If first client, start the streaming
|
|
30
|
+
if (stream.clients.size === 1 && !stream.isActive) {
|
|
31
|
+
await this.activateStream(stream);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Stop streaming to a specific client
|
|
36
|
+
*/
|
|
37
|
+
stopStream(paneId, client) {
|
|
38
|
+
const stream = this.streams.get(paneId);
|
|
39
|
+
if (!stream)
|
|
40
|
+
return;
|
|
41
|
+
// Remove client
|
|
42
|
+
stream.clients.delete(client);
|
|
43
|
+
// If no more clients, deactivate stream
|
|
44
|
+
if (stream.clients.size === 0) {
|
|
45
|
+
this.deactivateStream(stream);
|
|
46
|
+
this.streams.delete(paneId);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Initialize stream info for a pane
|
|
51
|
+
*/
|
|
52
|
+
async initializeStream(paneId, tmuxPaneId) {
|
|
53
|
+
// Get pane dimensions
|
|
54
|
+
const dimensions = this.getPaneDimensions(tmuxPaneId);
|
|
55
|
+
// Capture current state
|
|
56
|
+
const content = this.capturePaneContent(tmuxPaneId);
|
|
57
|
+
// Create pipe path
|
|
58
|
+
const pipePath = `/tmp/dmux-pipe-${paneId}-${Date.now()}`;
|
|
59
|
+
return {
|
|
60
|
+
paneId,
|
|
61
|
+
tmuxPaneId,
|
|
62
|
+
pipePath,
|
|
63
|
+
clients: new Set(),
|
|
64
|
+
width: dimensions.width,
|
|
65
|
+
height: dimensions.height,
|
|
66
|
+
lastContent: content,
|
|
67
|
+
isActive: false
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Send initial state to a new client
|
|
72
|
+
*/
|
|
73
|
+
async sendInitialState(stream, client) {
|
|
74
|
+
// Get cursor position from tmux
|
|
75
|
+
const cursorPos = this.getCursorPosition(stream.tmuxPaneId);
|
|
76
|
+
// Send raw content with ANSI codes - frontend will parse
|
|
77
|
+
const initMessage = {
|
|
78
|
+
type: 'init',
|
|
79
|
+
width: stream.width,
|
|
80
|
+
height: stream.height,
|
|
81
|
+
content: stream.lastContent,
|
|
82
|
+
cursorRow: cursorPos.row,
|
|
83
|
+
cursorCol: cursorPos.col,
|
|
84
|
+
timestamp: Date.now()
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
// Send as delimited message using protocol formatter
|
|
88
|
+
client.push(formatStreamMessage(initMessage));
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// Client disconnected during init
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get cursor position from tmux
|
|
96
|
+
*/
|
|
97
|
+
getCursorPosition(tmuxPaneId) {
|
|
98
|
+
try {
|
|
99
|
+
const output = execSync(`tmux display-message -p -t ${tmuxPaneId} -F "#{cursor_y},#{cursor_x}"`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
100
|
+
const [row, col] = output.split(',').map(Number);
|
|
101
|
+
return { row: row || 0, col: col || 0 };
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return { row: 0, col: 0 };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Activate streaming for a pane (start piping and monitoring)
|
|
109
|
+
*/
|
|
110
|
+
async activateStream(stream) {
|
|
111
|
+
if (stream.isActive)
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
// Stop any existing pipe-pane first
|
|
115
|
+
try {
|
|
116
|
+
execSync(`tmux pipe-pane -t ${stream.tmuxPaneId}`, { stdio: 'pipe' });
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// No existing pipe, which is fine
|
|
120
|
+
}
|
|
121
|
+
// Create empty pipe file (using touch to avoid any output)
|
|
122
|
+
execSync(`> ${stream.pipePath}`, { stdio: 'pipe' });
|
|
123
|
+
// Start tmux pipe-pane
|
|
124
|
+
const pipeCmd = `tmux pipe-pane -t ${stream.tmuxPaneId} -o 'cat >> ${stream.pipePath}'`;
|
|
125
|
+
execSync(pipeCmd, { stdio: 'pipe' });
|
|
126
|
+
// Small delay to ensure pipe-pane is ready
|
|
127
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
128
|
+
// Start tailing the pipe file
|
|
129
|
+
stream.tailProcess = spawn('tail', ['-f', stream.pipePath]);
|
|
130
|
+
// Buffer for accumulating output
|
|
131
|
+
let outputBuffer = '';
|
|
132
|
+
let bufferTimeout = null;
|
|
133
|
+
// String decoder to handle multi-byte UTF-8 sequences across chunks
|
|
134
|
+
const decoder = new StringDecoder('utf8');
|
|
135
|
+
/**
|
|
136
|
+
* Check if string ends with incomplete ANSI escape sequence
|
|
137
|
+
* Returns the index where the incomplete sequence starts, or -1 if complete
|
|
138
|
+
*/
|
|
139
|
+
const findIncompleteEscape = (str) => {
|
|
140
|
+
// Check last few characters for start of escape sequences
|
|
141
|
+
for (let i = Math.max(0, str.length - 10); i < str.length; i++) {
|
|
142
|
+
if (str.charCodeAt(i) === 27) { // ESC
|
|
143
|
+
const remaining = str.substring(i);
|
|
144
|
+
// ESC without following character
|
|
145
|
+
if (remaining.length === 1)
|
|
146
|
+
return i;
|
|
147
|
+
// ESC[ (CSI) without terminator
|
|
148
|
+
if (remaining[1] === '[') {
|
|
149
|
+
let hasTerminator = false;
|
|
150
|
+
let j = 2;
|
|
151
|
+
for (; j < remaining.length; j++) {
|
|
152
|
+
const c = remaining.charCodeAt(j);
|
|
153
|
+
// Valid CSI parameter/intermediate bytes: 0-9, ;, space through /
|
|
154
|
+
if ((c >= 48 && c <= 57) || c === 59 || (c >= 32 && c <= 47)) {
|
|
155
|
+
continue; // Valid parameter character, keep looking
|
|
156
|
+
}
|
|
157
|
+
// Final byte (terminator): @ through ~
|
|
158
|
+
if (c >= 64 && c <= 126) {
|
|
159
|
+
hasTerminator = true;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
// Invalid character, sequence is broken - don't buffer it
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
if (!hasTerminator && j === remaining.length) {
|
|
166
|
+
// Reached end without finding terminator, and all chars were valid
|
|
167
|
+
return i;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ESC] (OSC) without terminator (BEL or ESC\)
|
|
171
|
+
if (remaining[1] === ']') {
|
|
172
|
+
let hasTerminator = false;
|
|
173
|
+
for (let j = 2; j < remaining.length; j++) {
|
|
174
|
+
if (remaining.charCodeAt(j) === 7) { // BEL
|
|
175
|
+
hasTerminator = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
if (remaining.charCodeAt(j) === 27 && remaining[j + 1] === '\\') { // ESC\
|
|
179
|
+
hasTerminator = true;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!hasTerminator)
|
|
184
|
+
return i;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return -1;
|
|
189
|
+
};
|
|
190
|
+
// Handle tail output
|
|
191
|
+
stream.tailProcess.stdout?.on('data', (data) => {
|
|
192
|
+
if (this.isShuttingDown)
|
|
193
|
+
return;
|
|
194
|
+
// Use StringDecoder to properly handle multi-byte UTF-8 sequences
|
|
195
|
+
const chunk = decoder.write(data);
|
|
196
|
+
outputBuffer += chunk;
|
|
197
|
+
// Clear existing timeout
|
|
198
|
+
if (bufferTimeout) {
|
|
199
|
+
clearTimeout(bufferTimeout);
|
|
200
|
+
}
|
|
201
|
+
// Buffer for 16ms (60fps)
|
|
202
|
+
bufferTimeout = setTimeout(() => {
|
|
203
|
+
if (outputBuffer) {
|
|
204
|
+
// Check for incomplete escape sequences
|
|
205
|
+
const incompleteIndex = findIncompleteEscape(outputBuffer);
|
|
206
|
+
if (incompleteIndex >= 0) {
|
|
207
|
+
// Send complete portion, keep incomplete sequence in buffer
|
|
208
|
+
const completeOutput = outputBuffer.substring(0, incompleteIndex);
|
|
209
|
+
outputBuffer = outputBuffer.substring(incompleteIndex);
|
|
210
|
+
if (completeOutput) {
|
|
211
|
+
this.processAndSendUpdates(stream, completeOutput);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// Everything is complete, send it all
|
|
216
|
+
this.processAndSendUpdates(stream, outputBuffer);
|
|
217
|
+
outputBuffer = '';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}, 16);
|
|
221
|
+
});
|
|
222
|
+
// Handle tail process end - flush any remaining bytes
|
|
223
|
+
stream.tailProcess.stdout?.on('end', () => {
|
|
224
|
+
const remaining = decoder.end();
|
|
225
|
+
if (remaining) {
|
|
226
|
+
outputBuffer += remaining;
|
|
227
|
+
if (outputBuffer) {
|
|
228
|
+
this.processAndSendUpdates(stream, outputBuffer);
|
|
229
|
+
outputBuffer = '';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
// Handle tail process errors
|
|
234
|
+
stream.tailProcess.on('error', (error) => {
|
|
235
|
+
// Silently handle tail errors - they're usually benign
|
|
236
|
+
});
|
|
237
|
+
// Start resize monitoring
|
|
238
|
+
stream.resizeCheckInterval = setInterval(() => {
|
|
239
|
+
this.checkForResize(stream);
|
|
240
|
+
}, 500);
|
|
241
|
+
// Periodic full refresh to fix drift from patch-based streaming
|
|
242
|
+
// Patches work well for simple terminal output, but complex TUI apps (Ink, etc.)
|
|
243
|
+
// use cursor positioning that doesn't replay correctly. Full refresh keeps in sync.
|
|
244
|
+
stream.refreshInterval = setInterval(() => {
|
|
245
|
+
const content = this.capturePaneContent(stream.tmuxPaneId);
|
|
246
|
+
// Skip refresh if content is empty (pane might be closed or capture failed)
|
|
247
|
+
if (!content || content.trim().length === 0) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const cursorPos = this.getCursorPosition(stream.tmuxPaneId);
|
|
251
|
+
// Send full refresh as INIT message to reset buffer
|
|
252
|
+
const refreshMessage = {
|
|
253
|
+
type: 'init',
|
|
254
|
+
width: stream.width,
|
|
255
|
+
height: stream.height,
|
|
256
|
+
content: content,
|
|
257
|
+
cursorRow: cursorPos.row,
|
|
258
|
+
cursorCol: cursorPos.col,
|
|
259
|
+
timestamp: Date.now()
|
|
260
|
+
};
|
|
261
|
+
stream.clients.forEach(client => {
|
|
262
|
+
try {
|
|
263
|
+
client.push(formatStreamMessage(refreshMessage));
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
stream.clients.delete(client);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
stream.lastContent = content;
|
|
270
|
+
}, 2000); // Full refresh every 2 seconds to fix patch drift
|
|
271
|
+
stream.isActive = true;
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
// Stream activation failed silently
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Deactivate streaming for a pane
|
|
279
|
+
*/
|
|
280
|
+
deactivateStream(stream) {
|
|
281
|
+
// Stop resize monitoring
|
|
282
|
+
if (stream.resizeCheckInterval) {
|
|
283
|
+
clearInterval(stream.resizeCheckInterval);
|
|
284
|
+
stream.resizeCheckInterval = undefined;
|
|
285
|
+
}
|
|
286
|
+
// Stop refresh interval
|
|
287
|
+
if (stream.refreshInterval) {
|
|
288
|
+
clearInterval(stream.refreshInterval);
|
|
289
|
+
stream.refreshInterval = undefined;
|
|
290
|
+
}
|
|
291
|
+
// Stop tail process
|
|
292
|
+
if (stream.tailProcess) {
|
|
293
|
+
stream.tailProcess.kill();
|
|
294
|
+
stream.tailProcess = undefined;
|
|
295
|
+
}
|
|
296
|
+
// Stop tmux pipe
|
|
297
|
+
try {
|
|
298
|
+
execSync(`tmux pipe-pane -t ${stream.tmuxPaneId}`, { stdio: 'pipe' });
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
// Ignore pipe-pane stop errors
|
|
302
|
+
}
|
|
303
|
+
// Clean up pipe file
|
|
304
|
+
if (existsSync(stream.pipePath)) {
|
|
305
|
+
try {
|
|
306
|
+
unlinkSync(stream.pipePath);
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
// Ignore cleanup errors
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
stream.isActive = false;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Process output and send updates to clients
|
|
316
|
+
*/
|
|
317
|
+
processAndSendUpdates(stream, output) {
|
|
318
|
+
// Get current cursor position for accurate rendering
|
|
319
|
+
const cursorPos = this.getCursorPosition(stream.tmuxPaneId);
|
|
320
|
+
// DEBUG: Log patch details (disabled)
|
|
321
|
+
// const first100 = output.substring(0, 100).replace(/\x1b/g, '\\x1b').replace(/\r/g, '\\r').replace(/\n/g, '\\n');
|
|
322
|
+
// const last100 = output.substring(Math.max(0, output.length - 100)).replace(/\x1b/g, '\\x1b').replace(/\r/g, '\\r').replace(/\n/g, '\\n');
|
|
323
|
+
// console.error(`[PATCH OUT] pane=${stream.paneId} cursor=(${cursorPos.row},${cursorPos.col}) len=${output.length}`);
|
|
324
|
+
// console.error(`[PATCH OUT] first100: ${first100}`);
|
|
325
|
+
// console.error(`[PATCH OUT] last100: ${last100}`);
|
|
326
|
+
// Send raw output with ANSI codes - frontend will parse
|
|
327
|
+
// Keep \r\n sequences - frontend handles them properly
|
|
328
|
+
const patchMessage = {
|
|
329
|
+
type: 'patch',
|
|
330
|
+
changes: [{
|
|
331
|
+
row: 0,
|
|
332
|
+
col: 0,
|
|
333
|
+
text: output
|
|
334
|
+
}],
|
|
335
|
+
cursorRow: cursorPos.row,
|
|
336
|
+
cursorCol: cursorPos.col,
|
|
337
|
+
timestamp: Date.now()
|
|
338
|
+
};
|
|
339
|
+
// Send to all connected clients
|
|
340
|
+
stream.clients.forEach(client => {
|
|
341
|
+
try {
|
|
342
|
+
// Send as delimited message using protocol formatter
|
|
343
|
+
client.push(formatStreamMessage(patchMessage));
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
// Client disconnected, remove from list
|
|
347
|
+
stream.clients.delete(client);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
// Keep raw content for new clients
|
|
351
|
+
stream.lastContent += output;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if pane has been resized
|
|
355
|
+
*/
|
|
356
|
+
checkForResize(stream) {
|
|
357
|
+
const dimensions = this.getPaneDimensions(stream.tmuxPaneId);
|
|
358
|
+
if (dimensions.width !== stream.width || dimensions.height !== stream.height) {
|
|
359
|
+
// Pane was resized
|
|
360
|
+
stream.width = dimensions.width;
|
|
361
|
+
stream.height = dimensions.height;
|
|
362
|
+
// Capture new full state
|
|
363
|
+
const content = this.capturePaneContent(stream.tmuxPaneId);
|
|
364
|
+
stream.lastContent = content;
|
|
365
|
+
// Send resize message with raw content - frontend will parse
|
|
366
|
+
const resizeMessage = {
|
|
367
|
+
type: 'resize',
|
|
368
|
+
width: dimensions.width,
|
|
369
|
+
height: dimensions.height,
|
|
370
|
+
content: content,
|
|
371
|
+
timestamp: Date.now()
|
|
372
|
+
};
|
|
373
|
+
stream.clients.forEach(client => {
|
|
374
|
+
try {
|
|
375
|
+
// Send as delimited message using protocol formatter
|
|
376
|
+
client.push(formatStreamMessage(resizeMessage));
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
// Client disconnected, remove from list
|
|
380
|
+
stream.clients.delete(client);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
// Restart piping after resize
|
|
384
|
+
this.restartPiping(stream);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Restart piping after a resize
|
|
389
|
+
*/
|
|
390
|
+
restartPiping(stream) {
|
|
391
|
+
// Stop current pipe
|
|
392
|
+
try {
|
|
393
|
+
execSync(`tmux pipe-pane -t ${stream.tmuxPaneId}`, { stdio: 'pipe' });
|
|
394
|
+
}
|
|
395
|
+
catch { }
|
|
396
|
+
// Kill tail process
|
|
397
|
+
if (stream.tailProcess) {
|
|
398
|
+
stream.tailProcess.kill();
|
|
399
|
+
}
|
|
400
|
+
// Clean up old pipe file
|
|
401
|
+
if (existsSync(stream.pipePath)) {
|
|
402
|
+
try {
|
|
403
|
+
unlinkSync(stream.pipePath);
|
|
404
|
+
}
|
|
405
|
+
catch { }
|
|
406
|
+
}
|
|
407
|
+
// Create new pipe path
|
|
408
|
+
stream.pipePath = `/tmp/dmux-pipe-${stream.paneId}-${Date.now()}`;
|
|
409
|
+
// Restart piping
|
|
410
|
+
setTimeout(() => {
|
|
411
|
+
if (stream.isActive && !this.isShuttingDown) {
|
|
412
|
+
this.activateStream(stream);
|
|
413
|
+
}
|
|
414
|
+
}, 100);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Get pane dimensions from tmux
|
|
418
|
+
*/
|
|
419
|
+
getPaneDimensions(tmuxPaneId) {
|
|
420
|
+
try {
|
|
421
|
+
const output = execSync(`tmux display-message -p -t ${tmuxPaneId} -F "#{pane_width}x#{pane_height}"`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
422
|
+
const [width, height] = output.split('x').map(Number);
|
|
423
|
+
return { width: width || 80, height: height || 24 };
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
// Return defaults on error
|
|
427
|
+
return { width: 80, height: 24 }; // Default dimensions
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Capture current pane content with ANSI codes
|
|
432
|
+
* Only captures the visible area (no scrollback) so cursor position matches
|
|
433
|
+
*/
|
|
434
|
+
capturePaneContent(tmuxPaneId) {
|
|
435
|
+
try {
|
|
436
|
+
// -p: print to stdout
|
|
437
|
+
// -e: include escape sequences
|
|
438
|
+
// -J: join wrapped lines
|
|
439
|
+
// Captures only visible pane (no -S means current screen)
|
|
440
|
+
return execSync(`tmux capture-pane -epJ -t ${tmuxPaneId}`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
// Return empty on error
|
|
444
|
+
return '';
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Get statistics about active streams
|
|
449
|
+
*/
|
|
450
|
+
getStats() {
|
|
451
|
+
const streams = Array.from(this.streams.entries()).map(([paneId, stream]) => ({
|
|
452
|
+
paneId,
|
|
453
|
+
clients: stream.clients.size,
|
|
454
|
+
dimensions: `${stream.width}x${stream.height}`
|
|
455
|
+
}));
|
|
456
|
+
const totalClients = streams.reduce((sum, s) => sum + s.clients, 0);
|
|
457
|
+
return {
|
|
458
|
+
activeStreams: this.streams.size,
|
|
459
|
+
totalClients,
|
|
460
|
+
streams
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Shutdown all streams
|
|
465
|
+
*/
|
|
466
|
+
async shutdown() {
|
|
467
|
+
this.isShuttingDown = true;
|
|
468
|
+
// Deactivate all streams
|
|
469
|
+
for (const stream of this.streams.values()) {
|
|
470
|
+
this.deactivateStream(stream);
|
|
471
|
+
}
|
|
472
|
+
this.streams.clear();
|
|
473
|
+
this.removeAllListeners();
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
// Export singleton instance
|
|
477
|
+
let instance = null;
|
|
478
|
+
export function getTerminalStreamer() {
|
|
479
|
+
if (!instance) {
|
|
480
|
+
instance = new TerminalStreamer();
|
|
481
|
+
}
|
|
482
|
+
return instance;
|
|
483
|
+
}
|
|
484
|
+
export function resetTerminalStreamer() {
|
|
485
|
+
if (instance) {
|
|
486
|
+
instance.shutdown();
|
|
487
|
+
instance = null;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
//# sourceMappingURL=TerminalStreamer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TerminalStreamer.js","sourceRoot":"","sources":["../../src/services/TerminalStreamer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class TunnelService {
|
|
2
|
+
private tunnel;
|
|
3
|
+
private tunnelUrl;
|
|
4
|
+
start(port: number): Promise<string>;
|
|
5
|
+
stop(): Promise<void>;
|
|
6
|
+
getUrl(): string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare const tunnelService: TunnelService;
|
|
9
|
+
//# sourceMappingURL=TunnelService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TunnelService.d.ts","sourceRoot":"","sources":["../../src/services/TunnelService.ts"],"names":[],"mappings":"AAEA,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAuB;IAElC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBpC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,MAAM,IAAI,MAAM,GAAG,IAAI;CAGxB;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { startTunnel } from 'untun';
|
|
2
|
+
export class TunnelService {
|
|
3
|
+
tunnel = null;
|
|
4
|
+
tunnelUrl = null;
|
|
5
|
+
async start(port) {
|
|
6
|
+
try {
|
|
7
|
+
this.tunnel = await startTunnel({
|
|
8
|
+
port,
|
|
9
|
+
acceptCloudflareNotice: true
|
|
10
|
+
});
|
|
11
|
+
this.tunnelUrl = await this.tunnel.getURL();
|
|
12
|
+
if (!this.tunnelUrl) {
|
|
13
|
+
throw new Error('Tunnel URL is null');
|
|
14
|
+
}
|
|
15
|
+
return this.tunnelUrl;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error('Failed to start tunnel:', error);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async stop() {
|
|
23
|
+
if (this.tunnel) {
|
|
24
|
+
await this.tunnel.close();
|
|
25
|
+
this.tunnel = null;
|
|
26
|
+
this.tunnelUrl = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
getUrl() {
|
|
30
|
+
return this.tunnelUrl;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export const tunnelService = new TunnelService();
|
|
34
|
+
//# sourceMappingURL=TunnelService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TunnelService.js","sourceRoot":"","sources":["../../src/services/TunnelService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,MAAM,OAAO,aAAa;IAChB,MAAM,GAAQ,IAAI,CAAC;IACnB,SAAS,GAAkB,IAAI,CAAC;IAExC,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,MAAM,WAAW,CAAC;gBAC9B,IAAI;gBACJ,sBAAsB,EAAE,IAAI;aAC7B,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { OutboundMessage } from '../workers/WorkerMessages.js';
|
|
3
|
+
export type MessageHandler = (paneId: string, message: OutboundMessage) => void | Promise<void>;
|
|
4
|
+
export interface MessageSubscription {
|
|
5
|
+
unsubscribe: () => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Central message router for worker communication
|
|
9
|
+
* Handles message distribution and subscription management
|
|
10
|
+
*/
|
|
11
|
+
export declare class WorkerMessageBus extends EventEmitter {
|
|
12
|
+
private subscribers;
|
|
13
|
+
private responseHandlers;
|
|
14
|
+
private requestTimeouts;
|
|
15
|
+
/**
|
|
16
|
+
* Handle incoming message from a worker
|
|
17
|
+
*/
|
|
18
|
+
handleWorkerMessage(paneId: string, message: OutboundMessage): void;
|
|
19
|
+
/**
|
|
20
|
+
* Subscribe to specific message types
|
|
21
|
+
*/
|
|
22
|
+
subscribe(messageType: string, handler: MessageHandler): MessageSubscription;
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe to multiple message types at once
|
|
25
|
+
*/
|
|
26
|
+
subscribeMultiple(messageTypes: string[], handler: MessageHandler): MessageSubscription;
|
|
27
|
+
/**
|
|
28
|
+
* Wait for a response to a specific request
|
|
29
|
+
*/
|
|
30
|
+
waitForResponse(requestId: string, timeoutMs?: number): Promise<OutboundMessage>;
|
|
31
|
+
/**
|
|
32
|
+
* Clear all subscriptions for a specific message type
|
|
33
|
+
*/
|
|
34
|
+
clearSubscriptions(messageType?: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get statistics about message bus activity
|
|
37
|
+
*/
|
|
38
|
+
getStats(): {
|
|
39
|
+
subscriptionCount: number;
|
|
40
|
+
pendingResponses: number;
|
|
41
|
+
messageTypes: string[];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Cleanup resources
|
|
45
|
+
*/
|
|
46
|
+
destroy(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=WorkerMessageBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerMessageBus.d.ts","sourceRoot":"","sources":["../../src/services/WorkerMessageBus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,8BAA8B,CAAC;AAEpF,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhG,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,gBAAgB,CAA0D;IAClF,OAAO,CAAC,eAAe,CAAqC;IAE5D;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAiCnE;;OAEG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,mBAAmB;IAe5E;;OAEG;IACH,iBAAiB,CACf,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,cAAc,GACtB,mBAAmB;IAUtB;;OAEG;IACH,eAAe,CACb,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,eAAe,CAAC;IAkB3B;;OAEG;IACH,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ9C;;OAEG;IACH,QAAQ,IAAI;QACV,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB;IAWD;;OAEG;IACH,OAAO,IAAI,IAAI;CAYhB"}
|