nikcli-remote 1.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/chunk-MCKGQKYU.js +15 -0
- package/dist/chunk-TJTKYXIZ.js +2782 -0
- package/dist/index.cjs +6804 -0
- package/dist/index.d.cts +372 -0
- package/dist/index.d.ts +372 -0
- package/dist/index.js +155 -0
- package/dist/localtunnel-XT32JGNN.js +3805 -0
- package/dist/server-XW6FLG7E.js +7 -0
- package/package.json +58 -0
- package/src/index.ts +82 -0
- package/src/qrcode.ts +164 -0
- package/src/server.ts +562 -0
- package/src/terminal.ts +163 -0
- package/src/tunnel.ts +258 -0
- package/src/types.ts +169 -0
- package/src/web-client.ts +657 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @nikcli/remote - Type definitions
|
|
5
|
+
*/
|
|
6
|
+
type SessionStatus = 'starting' | 'waiting' | 'connected' | 'stopped' | 'error';
|
|
7
|
+
type TunnelProvider = 'localtunnel' | 'cloudflared' | 'ngrok' | 'none';
|
|
8
|
+
interface DeviceInfo {
|
|
9
|
+
id: string;
|
|
10
|
+
userAgent?: string;
|
|
11
|
+
connectedAt: Date;
|
|
12
|
+
lastActivity: Date;
|
|
13
|
+
ip?: string;
|
|
14
|
+
}
|
|
15
|
+
interface RemoteSession {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
qrCode: string;
|
|
19
|
+
qrUrl: string;
|
|
20
|
+
localUrl: string;
|
|
21
|
+
tunnelUrl?: string;
|
|
22
|
+
status: SessionStatus;
|
|
23
|
+
connectedDevices: DeviceInfo[];
|
|
24
|
+
startedAt: Date;
|
|
25
|
+
lastActivity: Date;
|
|
26
|
+
error?: string;
|
|
27
|
+
port: number;
|
|
28
|
+
}
|
|
29
|
+
interface ServerConfig {
|
|
30
|
+
/** Port to listen on (0 = auto-assign) */
|
|
31
|
+
port: number;
|
|
32
|
+
/** Host to bind to */
|
|
33
|
+
host: string;
|
|
34
|
+
/** Enable tunnel for public access */
|
|
35
|
+
enableTunnel: boolean;
|
|
36
|
+
/** Tunnel provider */
|
|
37
|
+
tunnelProvider: TunnelProvider;
|
|
38
|
+
/** Session secret for authentication */
|
|
39
|
+
sessionSecret?: string;
|
|
40
|
+
/** Maximum concurrent connections */
|
|
41
|
+
maxConnections: number;
|
|
42
|
+
/** Heartbeat interval in ms */
|
|
43
|
+
heartbeatInterval: number;
|
|
44
|
+
/** Shell command to spawn */
|
|
45
|
+
shell: string;
|
|
46
|
+
/** Initial terminal columns */
|
|
47
|
+
cols: number;
|
|
48
|
+
/** Initial terminal rows */
|
|
49
|
+
rows: number;
|
|
50
|
+
/** Working directory for shell */
|
|
51
|
+
cwd?: string;
|
|
52
|
+
/** Environment variables */
|
|
53
|
+
env?: Record<string, string>;
|
|
54
|
+
/** Enable terminal (PTY) */
|
|
55
|
+
enableTerminal: boolean;
|
|
56
|
+
/** Session timeout in ms (0 = no timeout) */
|
|
57
|
+
sessionTimeout: number;
|
|
58
|
+
}
|
|
59
|
+
interface BroadcastMessage {
|
|
60
|
+
type: string;
|
|
61
|
+
payload: unknown;
|
|
62
|
+
timestamp?: number;
|
|
63
|
+
}
|
|
64
|
+
interface RemoteNotification {
|
|
65
|
+
type: 'success' | 'error' | 'warning' | 'info';
|
|
66
|
+
title: string;
|
|
67
|
+
body: string;
|
|
68
|
+
data?: unknown;
|
|
69
|
+
}
|
|
70
|
+
interface ClientMessage {
|
|
71
|
+
type: string;
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
}
|
|
74
|
+
interface ServerMessage {
|
|
75
|
+
type: string;
|
|
76
|
+
payload?: unknown;
|
|
77
|
+
timestamp: number;
|
|
78
|
+
}
|
|
79
|
+
interface TerminalData {
|
|
80
|
+
data: string;
|
|
81
|
+
}
|
|
82
|
+
interface TerminalResize {
|
|
83
|
+
cols: number;
|
|
84
|
+
rows: number;
|
|
85
|
+
}
|
|
86
|
+
interface CommandMessage {
|
|
87
|
+
command: string;
|
|
88
|
+
args?: string[];
|
|
89
|
+
}
|
|
90
|
+
interface ClientConnection {
|
|
91
|
+
id: string;
|
|
92
|
+
authenticated: boolean;
|
|
93
|
+
device: DeviceInfo;
|
|
94
|
+
lastPing: number;
|
|
95
|
+
}
|
|
96
|
+
declare const DEFAULT_CONFIG: ServerConfig;
|
|
97
|
+
declare const MessageTypes: {
|
|
98
|
+
readonly AUTH_REQUIRED: "auth:required";
|
|
99
|
+
readonly AUTH: "auth";
|
|
100
|
+
readonly AUTH_SUCCESS: "auth:success";
|
|
101
|
+
readonly AUTH_FAILED: "auth:failed";
|
|
102
|
+
readonly TERMINAL_OUTPUT: "terminal:output";
|
|
103
|
+
readonly TERMINAL_INPUT: "terminal:input";
|
|
104
|
+
readonly TERMINAL_RESIZE: "terminal:resize";
|
|
105
|
+
readonly TERMINAL_EXIT: "terminal:exit";
|
|
106
|
+
readonly TERMINAL_CLEAR: "terminal:clear";
|
|
107
|
+
readonly NOTIFICATION: "notification";
|
|
108
|
+
readonly PING: "ping";
|
|
109
|
+
readonly PONG: "pong";
|
|
110
|
+
readonly SESSION_INFO: "session:info";
|
|
111
|
+
readonly SESSION_END: "session:end";
|
|
112
|
+
readonly COMMAND: "command";
|
|
113
|
+
readonly COMMAND_RESULT: "command:result";
|
|
114
|
+
readonly AGENT_START: "agent:start";
|
|
115
|
+
readonly AGENT_PROGRESS: "agent:progress";
|
|
116
|
+
readonly AGENT_COMPLETE: "agent:complete";
|
|
117
|
+
readonly AGENT_ERROR: "agent:error";
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @nikcli/remote - Native Remote Server
|
|
122
|
+
* WebSocket-based remote terminal with mobile-friendly web client
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
interface RemoteServerEvents {
|
|
126
|
+
started: (session: RemoteSession) => void;
|
|
127
|
+
stopped: () => void;
|
|
128
|
+
'client:connected': (device: DeviceInfo) => void;
|
|
129
|
+
'client:disconnected': (device: DeviceInfo) => void;
|
|
130
|
+
'client:error': (clientId: string, error: Error) => void;
|
|
131
|
+
'tunnel:connected': (url: string) => void;
|
|
132
|
+
'tunnel:error': (error: Error) => void;
|
|
133
|
+
command: (cmd: {
|
|
134
|
+
clientId: string;
|
|
135
|
+
command: string;
|
|
136
|
+
args?: string[];
|
|
137
|
+
}) => void;
|
|
138
|
+
message: (client: ClientConnection, message: ClientMessage) => void;
|
|
139
|
+
error: (error: Error) => void;
|
|
140
|
+
}
|
|
141
|
+
declare class RemoteServer extends EventEmitter {
|
|
142
|
+
private config;
|
|
143
|
+
private httpServer;
|
|
144
|
+
private wss;
|
|
145
|
+
private clients;
|
|
146
|
+
private session;
|
|
147
|
+
private terminal;
|
|
148
|
+
private tunnel;
|
|
149
|
+
private heartbeatTimer;
|
|
150
|
+
private sessionTimeoutTimer;
|
|
151
|
+
private isRunning;
|
|
152
|
+
private sessionSecret;
|
|
153
|
+
constructor(config?: Partial<ServerConfig>);
|
|
154
|
+
/**
|
|
155
|
+
* Start the remote server
|
|
156
|
+
*/
|
|
157
|
+
start(options?: {
|
|
158
|
+
name?: string;
|
|
159
|
+
}): Promise<RemoteSession>;
|
|
160
|
+
/**
|
|
161
|
+
* Stop the server
|
|
162
|
+
*/
|
|
163
|
+
stop(): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Broadcast message to all authenticated clients
|
|
166
|
+
*/
|
|
167
|
+
broadcast(message: BroadcastMessage): void;
|
|
168
|
+
/**
|
|
169
|
+
* Send notification to clients
|
|
170
|
+
*/
|
|
171
|
+
notify(notification: RemoteNotification): void;
|
|
172
|
+
/**
|
|
173
|
+
* Get current session
|
|
174
|
+
*/
|
|
175
|
+
getSession(): RemoteSession | null;
|
|
176
|
+
/**
|
|
177
|
+
* Check if server is running
|
|
178
|
+
*/
|
|
179
|
+
isActive(): boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Get connected client count
|
|
182
|
+
*/
|
|
183
|
+
getConnectedCount(): number;
|
|
184
|
+
/**
|
|
185
|
+
* Write to terminal
|
|
186
|
+
*/
|
|
187
|
+
writeToTerminal(data: string): void;
|
|
188
|
+
/**
|
|
189
|
+
* Resize terminal
|
|
190
|
+
*/
|
|
191
|
+
resizeTerminal(cols: number, rows: number): void;
|
|
192
|
+
/**
|
|
193
|
+
* Setup WebSocket handlers
|
|
194
|
+
*/
|
|
195
|
+
private setupWebSocketHandlers;
|
|
196
|
+
/**
|
|
197
|
+
* Handle client message
|
|
198
|
+
*/
|
|
199
|
+
private handleClientMessage;
|
|
200
|
+
/**
|
|
201
|
+
* Handle authentication
|
|
202
|
+
*/
|
|
203
|
+
private handleAuth;
|
|
204
|
+
/**
|
|
205
|
+
* Handle HTTP request
|
|
206
|
+
*/
|
|
207
|
+
private handleHttpRequest;
|
|
208
|
+
/**
|
|
209
|
+
* Start heartbeat
|
|
210
|
+
*/
|
|
211
|
+
private startHeartbeat;
|
|
212
|
+
/**
|
|
213
|
+
* Start session timeout
|
|
214
|
+
*/
|
|
215
|
+
private startSessionTimeout;
|
|
216
|
+
/**
|
|
217
|
+
* Reset session timeout
|
|
218
|
+
*/
|
|
219
|
+
private resetSessionTimeout;
|
|
220
|
+
/**
|
|
221
|
+
* Get local IP
|
|
222
|
+
*/
|
|
223
|
+
private getLocalIP;
|
|
224
|
+
/**
|
|
225
|
+
* Generate session ID
|
|
226
|
+
*/
|
|
227
|
+
private generateSessionId;
|
|
228
|
+
/**
|
|
229
|
+
* Generate client ID
|
|
230
|
+
*/
|
|
231
|
+
private generateClientId;
|
|
232
|
+
/**
|
|
233
|
+
* Generate secret
|
|
234
|
+
*/
|
|
235
|
+
private generateSecret;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @nikcli/remote - Terminal Manager
|
|
240
|
+
* PTY-based terminal with fallback to basic spawn
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
interface TerminalConfig {
|
|
244
|
+
shell: string;
|
|
245
|
+
cols: number;
|
|
246
|
+
rows: number;
|
|
247
|
+
cwd?: string;
|
|
248
|
+
env?: Record<string, string>;
|
|
249
|
+
}
|
|
250
|
+
declare class TerminalManager extends EventEmitter {
|
|
251
|
+
private config;
|
|
252
|
+
private ptyProcess;
|
|
253
|
+
private process;
|
|
254
|
+
private running;
|
|
255
|
+
constructor(config: TerminalConfig);
|
|
256
|
+
/**
|
|
257
|
+
* Start the terminal
|
|
258
|
+
*/
|
|
259
|
+
start(): void;
|
|
260
|
+
/**
|
|
261
|
+
* Write data to terminal
|
|
262
|
+
*/
|
|
263
|
+
write(data: string): void;
|
|
264
|
+
/**
|
|
265
|
+
* Resize terminal
|
|
266
|
+
*/
|
|
267
|
+
resize(cols: number, rows: number): void;
|
|
268
|
+
/**
|
|
269
|
+
* Clear terminal
|
|
270
|
+
*/
|
|
271
|
+
clear(): void;
|
|
272
|
+
/**
|
|
273
|
+
* Kill terminal process
|
|
274
|
+
*/
|
|
275
|
+
destroy(): void;
|
|
276
|
+
/**
|
|
277
|
+
* Check if terminal is running
|
|
278
|
+
*/
|
|
279
|
+
isRunning(): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* Check if using PTY
|
|
282
|
+
*/
|
|
283
|
+
hasPty(): boolean;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* @nikcli/remote - Tunnel Manager
|
|
288
|
+
* Provides public URL access via various tunnel providers
|
|
289
|
+
*/
|
|
290
|
+
|
|
291
|
+
declare class TunnelManager {
|
|
292
|
+
private provider;
|
|
293
|
+
private process;
|
|
294
|
+
private url;
|
|
295
|
+
private tunnelInstance;
|
|
296
|
+
constructor(provider: TunnelProvider);
|
|
297
|
+
/**
|
|
298
|
+
* Create tunnel and return public URL
|
|
299
|
+
*/
|
|
300
|
+
create(port: number): Promise<string>;
|
|
301
|
+
/**
|
|
302
|
+
* Close tunnel
|
|
303
|
+
*/
|
|
304
|
+
close(): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* Get tunnel URL
|
|
307
|
+
*/
|
|
308
|
+
getUrl(): string | null;
|
|
309
|
+
/**
|
|
310
|
+
* Create localtunnel
|
|
311
|
+
*/
|
|
312
|
+
private createLocaltunnel;
|
|
313
|
+
/**
|
|
314
|
+
* Create localtunnel via CLI
|
|
315
|
+
*/
|
|
316
|
+
private createLocaltunnelCli;
|
|
317
|
+
/**
|
|
318
|
+
* Create cloudflared tunnel
|
|
319
|
+
*/
|
|
320
|
+
private createCloudflared;
|
|
321
|
+
/**
|
|
322
|
+
* Create ngrok tunnel
|
|
323
|
+
*/
|
|
324
|
+
private createNgrok;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Check if a tunnel provider is available
|
|
328
|
+
*/
|
|
329
|
+
declare function checkTunnelAvailability(provider: TunnelProvider): Promise<boolean>;
|
|
330
|
+
/**
|
|
331
|
+
* Find best available tunnel provider
|
|
332
|
+
*/
|
|
333
|
+
declare function findAvailableTunnel(): Promise<TunnelProvider | null>;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* @nikcli/remote - QR Code Generator
|
|
337
|
+
* Terminal QR code rendering for session URLs
|
|
338
|
+
*/
|
|
339
|
+
|
|
340
|
+
interface QROptions {
|
|
341
|
+
small?: boolean;
|
|
342
|
+
margin?: number;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Generate QR code string for terminal display
|
|
346
|
+
*/
|
|
347
|
+
declare function generateQR(url: string, options?: QROptions): Promise<string>;
|
|
348
|
+
/**
|
|
349
|
+
* Generate QR code as data URL (for web/image)
|
|
350
|
+
*/
|
|
351
|
+
declare function generateQRDataURL(url: string): Promise<string | null>;
|
|
352
|
+
/**
|
|
353
|
+
* Render session info with QR code
|
|
354
|
+
*/
|
|
355
|
+
declare function renderSessionCard(session: RemoteSession): Promise<string>;
|
|
356
|
+
/**
|
|
357
|
+
* Simple progress bar
|
|
358
|
+
*/
|
|
359
|
+
declare function progressBar(current: number, total: number, width?: number): string;
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @nikcli/remote - Mobile Web Client
|
|
363
|
+
* Touch-friendly terminal interface for mobile devices
|
|
364
|
+
*/
|
|
365
|
+
declare function getWebClient(): string;
|
|
366
|
+
|
|
367
|
+
declare function createRemoteServer(config?: Partial<ServerConfig>): Promise<{
|
|
368
|
+
server: RemoteServer;
|
|
369
|
+
session: RemoteSession;
|
|
370
|
+
}>;
|
|
371
|
+
|
|
372
|
+
export { type BroadcastMessage, type ClientConnection, type ClientMessage, type CommandMessage, DEFAULT_CONFIG, type DeviceInfo, MessageTypes, type RemoteNotification, RemoteServer, type RemoteServerEvents, type RemoteSession, type ServerConfig, type ServerMessage, type SessionStatus, type TerminalConfig, type TerminalData, TerminalManager, type TerminalResize, TunnelManager, type TunnelProvider, checkTunnelAvailability, createRemoteServer, findAvailableTunnel, generateQR, generateQRDataURL, getWebClient, progressBar, renderSessionCard };
|