raffel 1.1.21 → 1.1.25
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/README.md +55 -3
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +4 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/ssh-host-key.d.ts +17 -0
- package/dist/adapters/ssh-host-key.d.ts.map +1 -0
- package/dist/adapters/ssh-host-key.js +25 -0
- package/dist/adapters/ssh-host-key.js.map +1 -0
- package/dist/adapters/ssh-keys.d.ts +21 -0
- package/dist/adapters/ssh-keys.d.ts.map +1 -0
- package/dist/adapters/ssh-keys.js +211 -0
- package/dist/adapters/ssh-keys.js.map +1 -0
- package/dist/adapters/ssh-session.d.ts +54 -0
- package/dist/adapters/ssh-session.d.ts.map +1 -0
- package/dist/adapters/ssh-session.js +202 -0
- package/dist/adapters/ssh-session.js.map +1 -0
- package/dist/adapters/ssh-tui-bridge.d.ts +37 -0
- package/dist/adapters/ssh-tui-bridge.d.ts.map +1 -0
- package/dist/adapters/ssh-tui-bridge.js +90 -0
- package/dist/adapters/ssh-tui-bridge.js.map +1 -0
- package/dist/adapters/ssh-types.d.ts +268 -0
- package/dist/adapters/ssh-types.d.ts.map +1 -0
- package/dist/adapters/ssh-types.js +9 -0
- package/dist/adapters/ssh-types.js.map +1 -0
- package/dist/adapters/ssh.d.ts +43 -0
- package/dist/adapters/ssh.d.ts.map +1 -0
- package/dist/adapters/ssh.js +347 -0
- package/dist/adapters/ssh.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Adapter — Session factory
|
|
3
|
+
*
|
|
4
|
+
* Wraps an ssh2 ServerChannel into the user-facing SshSession surface.
|
|
5
|
+
* Owns the lifecycle: parses input keys, manages window-resize, dispatches
|
|
6
|
+
* close events, builds the lazy tuiuiu bridge.
|
|
7
|
+
*/
|
|
8
|
+
import { parseKeys } from './ssh-keys.js';
|
|
9
|
+
import { createTuiBridge } from './ssh-tui-bridge.js';
|
|
10
|
+
export function createSshSession(opts) {
|
|
11
|
+
const { id, user, authMethod, authData, client, env, channel, kind, command, subsystem } = opts;
|
|
12
|
+
let pty = opts.pty;
|
|
13
|
+
const abortController = new AbortController();
|
|
14
|
+
const resizeHandlers = new Set();
|
|
15
|
+
const closeHandlers = new Set();
|
|
16
|
+
let closed = false;
|
|
17
|
+
let tuiBridge = null;
|
|
18
|
+
// ----- raw key event channel -----
|
|
19
|
+
// We buffer parsed KeyEvents in a queue and resolve pending iterators.
|
|
20
|
+
const keyQueue = [];
|
|
21
|
+
let keyWaiter = null;
|
|
22
|
+
function pushKey(k) {
|
|
23
|
+
if (keyWaiter) {
|
|
24
|
+
const w = keyWaiter;
|
|
25
|
+
keyWaiter = null;
|
|
26
|
+
w({ value: k, done: false });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
keyQueue.push(k);
|
|
30
|
+
}
|
|
31
|
+
function endKeys() {
|
|
32
|
+
if (keyWaiter) {
|
|
33
|
+
const w = keyWaiter;
|
|
34
|
+
keyWaiter = null;
|
|
35
|
+
w({ value: undefined, done: true });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const onData = (chunk) => {
|
|
39
|
+
for (const k of parseKeys(chunk))
|
|
40
|
+
pushKey(k);
|
|
41
|
+
};
|
|
42
|
+
channel.on('data', onData);
|
|
43
|
+
channel.once('close', () => notifyClosed());
|
|
44
|
+
channel.once('end', () => notifyClosed());
|
|
45
|
+
function notifyClosed() {
|
|
46
|
+
if (closed)
|
|
47
|
+
return;
|
|
48
|
+
closed = true;
|
|
49
|
+
abortController.abort();
|
|
50
|
+
channel.off('data', onData);
|
|
51
|
+
endKeys();
|
|
52
|
+
for (const h of closeHandlers) {
|
|
53
|
+
try {
|
|
54
|
+
h();
|
|
55
|
+
}
|
|
56
|
+
catch { /* user handler error — swallow */ }
|
|
57
|
+
}
|
|
58
|
+
if (tuiBridge) {
|
|
59
|
+
try {
|
|
60
|
+
tuiBridge.destroy();
|
|
61
|
+
}
|
|
62
|
+
catch { /* noop */ }
|
|
63
|
+
tuiBridge = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ----- stdout / stderr as Writable-like views over channel -----
|
|
67
|
+
// ssh2 ServerChannel already IS a Duplex stream — we expose it directly
|
|
68
|
+
// as `stdout`. For consistency with Node's TTY model, downstream code
|
|
69
|
+
// calls `session.write(...)` or accesses `session.stdout`.
|
|
70
|
+
const stdoutAsWritable = channel;
|
|
71
|
+
const session = {
|
|
72
|
+
id,
|
|
73
|
+
user,
|
|
74
|
+
authMethod,
|
|
75
|
+
authData,
|
|
76
|
+
client,
|
|
77
|
+
env,
|
|
78
|
+
pty,
|
|
79
|
+
kind,
|
|
80
|
+
command,
|
|
81
|
+
subsystem,
|
|
82
|
+
signal: abortController.signal,
|
|
83
|
+
get cols() {
|
|
84
|
+
return pty?.cols ?? 80;
|
|
85
|
+
},
|
|
86
|
+
get rows() {
|
|
87
|
+
return pty?.rows ?? 24;
|
|
88
|
+
},
|
|
89
|
+
get term() {
|
|
90
|
+
return pty?.term ?? 'xterm';
|
|
91
|
+
},
|
|
92
|
+
// ssh2 ServerChannel extends Duplex, so the same object IS both the
|
|
93
|
+
// readable input side and the writable output side. Multiple listeners
|
|
94
|
+
// on 'data' coexist fine (Node EventEmitter), so the key parser, the
|
|
95
|
+
// optional tui bridge, and user-attached listeners all receive chunks.
|
|
96
|
+
stdin: channel,
|
|
97
|
+
stdout: stdoutAsWritable,
|
|
98
|
+
stderr: channel.stderr,
|
|
99
|
+
write(text) {
|
|
100
|
+
if (closed)
|
|
101
|
+
return;
|
|
102
|
+
try {
|
|
103
|
+
channel.write(text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// channel closed — ignore
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
clear() {
|
|
110
|
+
this.write('\x1b[2J\x1b[H');
|
|
111
|
+
},
|
|
112
|
+
get keys() {
|
|
113
|
+
return {
|
|
114
|
+
[Symbol.asyncIterator]() {
|
|
115
|
+
return {
|
|
116
|
+
next() {
|
|
117
|
+
if (keyQueue.length > 0) {
|
|
118
|
+
return Promise.resolve({ value: keyQueue.shift(), done: false });
|
|
119
|
+
}
|
|
120
|
+
if (closed) {
|
|
121
|
+
return Promise.resolve({
|
|
122
|
+
value: undefined,
|
|
123
|
+
done: true,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
keyWaiter = resolve;
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
return() {
|
|
131
|
+
return Promise.resolve({
|
|
132
|
+
value: undefined,
|
|
133
|
+
done: true,
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
onResize(handler) {
|
|
141
|
+
resizeHandlers.add(handler);
|
|
142
|
+
},
|
|
143
|
+
onClose(handler) {
|
|
144
|
+
if (closed) {
|
|
145
|
+
// Already closed — fire async
|
|
146
|
+
queueMicrotask(handler);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
closeHandlers.add(handler);
|
|
150
|
+
},
|
|
151
|
+
close(exitCode = 0) {
|
|
152
|
+
if (closed)
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
channel.exit(exitCode);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// already exited
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
channel.end();
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// already ended
|
|
165
|
+
}
|
|
166
|
+
notifyClosed();
|
|
167
|
+
},
|
|
168
|
+
get tui() {
|
|
169
|
+
if (!tuiBridge) {
|
|
170
|
+
tuiBridge = createTuiBridge({
|
|
171
|
+
source: channel,
|
|
172
|
+
sink: stdoutAsWritable,
|
|
173
|
+
cols: session.cols,
|
|
174
|
+
rows: session.rows,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return { stdin: tuiBridge.stdin, stdout: tuiBridge.stdout };
|
|
178
|
+
},
|
|
179
|
+
_updateSize(cols, rows) {
|
|
180
|
+
if (pty)
|
|
181
|
+
pty = { ...pty, cols, rows };
|
|
182
|
+
else
|
|
183
|
+
pty = { cols, rows, width: 0, height: 0, term: 'xterm' };
|
|
184
|
+
for (const h of resizeHandlers) {
|
|
185
|
+
try {
|
|
186
|
+
h(cols, rows);
|
|
187
|
+
}
|
|
188
|
+
catch { /* swallow */ }
|
|
189
|
+
}
|
|
190
|
+
if (tuiBridge)
|
|
191
|
+
tuiBridge.updateSize(cols, rows);
|
|
192
|
+
},
|
|
193
|
+
_notifyClosed() {
|
|
194
|
+
notifyClosed();
|
|
195
|
+
},
|
|
196
|
+
_tuiBridge() {
|
|
197
|
+
return tuiBridge;
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
return session;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=ssh-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-session.js","sourceRoot":"","sources":["../../src/adapters/ssh-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Adapter — tuiuiu.js bridge
|
|
3
|
+
*
|
|
4
|
+
* Wraps SSH session stdin/stdout streams as TTY-compatible streams that
|
|
5
|
+
* tuiuiu.js `render()` (and similar TUI libs that check `isTTY`) can use
|
|
6
|
+
* transparently.
|
|
7
|
+
*
|
|
8
|
+
* - `isTTY = true` so tuiuiu enters interactive mode
|
|
9
|
+
* - `columns` / `rows` exposed and kept in sync with SSH window-change
|
|
10
|
+
* - `setRawMode()` is a no-op (SSH already delivers raw input)
|
|
11
|
+
* - `'resize'` events forwarded so tuiuiu can re-layout
|
|
12
|
+
*
|
|
13
|
+
* The bridge does NOT depend on tuiuiu.js at runtime — it just produces
|
|
14
|
+
* streams compatible with what tuiuiu expects. Users dynamically import
|
|
15
|
+
* tuiuiu in their handler and pass `session.tui`.
|
|
16
|
+
*/
|
|
17
|
+
import type { Readable as ReadableType, Writable as WritableType } from 'node:stream';
|
|
18
|
+
import type { TtyReadable, TtyWritable } from './ssh-types.js';
|
|
19
|
+
export interface TuiBridge {
|
|
20
|
+
stdin: TtyReadable;
|
|
21
|
+
stdout: TtyWritable;
|
|
22
|
+
/** Update reported window size; emits 'resize' on stdout. */
|
|
23
|
+
updateSize(cols: number, rows: number): void;
|
|
24
|
+
/** Close both ends — for adapter cleanup. */
|
|
25
|
+
destroy(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a TTY-compatible {stdin, stdout} pair forwarding to/from the SSH
|
|
29
|
+
* channel's underlying streams.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createTuiBridge(opts: {
|
|
32
|
+
source: ReadableType;
|
|
33
|
+
sink: WritableType;
|
|
34
|
+
cols: number;
|
|
35
|
+
rows: number;
|
|
36
|
+
}): TuiBridge;
|
|
37
|
+
//# sourceMappingURL=ssh-tui-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-tui-bridge.d.ts","sourceRoot":"","sources":["../../src/adapters/ssh-tui-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE9D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,WAAW,CAAA;IACnB,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,6CAA6C;IAC7C,OAAO,IAAI,IAAI,CAAA;CAChB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,SAAS,CAsEZ"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Adapter — tuiuiu.js bridge
|
|
3
|
+
*
|
|
4
|
+
* Wraps SSH session stdin/stdout streams as TTY-compatible streams that
|
|
5
|
+
* tuiuiu.js `render()` (and similar TUI libs that check `isTTY`) can use
|
|
6
|
+
* transparently.
|
|
7
|
+
*
|
|
8
|
+
* - `isTTY = true` so tuiuiu enters interactive mode
|
|
9
|
+
* - `columns` / `rows` exposed and kept in sync with SSH window-change
|
|
10
|
+
* - `setRawMode()` is a no-op (SSH already delivers raw input)
|
|
11
|
+
* - `'resize'` events forwarded so tuiuiu can re-layout
|
|
12
|
+
*
|
|
13
|
+
* The bridge does NOT depend on tuiuiu.js at runtime — it just produces
|
|
14
|
+
* streams compatible with what tuiuiu expects. Users dynamically import
|
|
15
|
+
* tuiuiu in their handler and pass `session.tui`.
|
|
16
|
+
*/
|
|
17
|
+
import { Readable, Writable } from 'node:stream';
|
|
18
|
+
/**
|
|
19
|
+
* Build a TTY-compatible {stdin, stdout} pair forwarding to/from the SSH
|
|
20
|
+
* channel's underlying streams.
|
|
21
|
+
*/
|
|
22
|
+
export function createTuiBridge(opts) {
|
|
23
|
+
let cols = opts.cols;
|
|
24
|
+
let rows = opts.rows;
|
|
25
|
+
// --- stdin: a Readable that mirrors `source` and exposes TTY surface
|
|
26
|
+
const stdin = new Readable({
|
|
27
|
+
read() {
|
|
28
|
+
// pulled on demand from source via 'data' listener below
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
stdin.isTTY = true;
|
|
32
|
+
stdin.setRawMode =
|
|
33
|
+
function setRawMode() {
|
|
34
|
+
return this;
|
|
35
|
+
};
|
|
36
|
+
const onSourceData = (chunk) => {
|
|
37
|
+
stdin.push(chunk);
|
|
38
|
+
};
|
|
39
|
+
const onSourceEnd = () => {
|
|
40
|
+
stdin.push(null);
|
|
41
|
+
};
|
|
42
|
+
opts.source.on('data', onSourceData);
|
|
43
|
+
opts.source.once('end', onSourceEnd);
|
|
44
|
+
opts.source.once('close', onSourceEnd);
|
|
45
|
+
// --- stdout: a Writable that forwards to `sink` and exposes TTY surface
|
|
46
|
+
const stdout = new Writable({
|
|
47
|
+
write(chunk, _enc, cb) {
|
|
48
|
+
// Best-effort write; ignore failed writes (channel may have closed)
|
|
49
|
+
try {
|
|
50
|
+
opts.sink.write(chunk, cb);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
cb();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
stdout.isTTY = true;
|
|
58
|
+
Object.defineProperty(stdout, 'columns', {
|
|
59
|
+
get: () => cols,
|
|
60
|
+
configurable: true,
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(stdout, 'rows', {
|
|
63
|
+
get: () => rows,
|
|
64
|
+
configurable: true,
|
|
65
|
+
});
|
|
66
|
+
function updateSize(newCols, newRows) {
|
|
67
|
+
cols = newCols;
|
|
68
|
+
rows = newRows;
|
|
69
|
+
stdout.emit('resize');
|
|
70
|
+
}
|
|
71
|
+
function destroy() {
|
|
72
|
+
opts.source.off('data', onSourceData);
|
|
73
|
+
opts.source.off('end', onSourceEnd);
|
|
74
|
+
opts.source.off('close', onSourceEnd);
|
|
75
|
+
try {
|
|
76
|
+
stdin.push(null);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// already ended
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
stdout.end();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// already ended
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { stdin, stdout, updateSize, destroy };
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=ssh-tui-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-tui-bridge.js","sourceRoot":"","sources":["../../src/adapters/ssh-tui-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAahD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAK/B;IACC,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACpB,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IAEpB,sEAAsE;IACtE,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC;QACzB,IAAI;YACF,yDAAyD;QAC3D,CAAC;KACF,CAAwD,CACxD;IAAC,KAAuC,CAAC,KAAK,GAAG,IAAI,CACrD;IAAC,KAA4D,CAAC,UAAU;QACvE,SAAS,UAAU;YACjB,OAAO,IAAI,CAAA;QACb,CAAC,CAAA;IAEH,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;QACrC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC,CAAA;IACD,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC,CAAA;IACD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IAEtC,yEAAyE;IACzE,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC;QAC1B,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACnB,oEAAoE;YACpE,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAA;YACN,CAAC;QACH,CAAC;KACF,CAA2B,CAC3B;IAAC,MAAwC,CAAC,KAAK,GAAG,IAAI,CAAA;IACvD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE;QACvC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;QACf,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IACF,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;QACpC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;QACf,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IAEF,SAAS,UAAU,CAAC,OAAe,EAAE,OAAe;QAClD,IAAI,GAAG,OAAO,CAAA;QACd,IAAI,GAAG,OAAO,CAAA;QACd,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACvB,CAAC;IAED,SAAS,OAAO;QACd,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QACrC,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,EAAE,CAAA;QACd,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAA;AAC/C,CAAC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Adapter — Types
|
|
3
|
+
*
|
|
4
|
+
* Public types for the SSH adapter. Requires `ssh2` (optional peer dep)
|
|
5
|
+
* at runtime. Types here are intentionally decoupled from ssh2's internal
|
|
6
|
+
* types so the public surface stays stable.
|
|
7
|
+
*/
|
|
8
|
+
import type { Readable, Writable } from 'node:stream';
|
|
9
|
+
import type { ConnectionFilter } from './utils/connection-filter.js';
|
|
10
|
+
/**
|
|
11
|
+
* A parsed key event from the SSH session stdin.
|
|
12
|
+
*
|
|
13
|
+
* Recognized names mirror Node's readline `keypress` event for familiarity:
|
|
14
|
+
* 'return' (Enter), 'escape', 'backspace', 'tab', 'space',
|
|
15
|
+
* 'up' | 'down' | 'left' | 'right', 'home' | 'end', 'pageup' | 'pagedown',
|
|
16
|
+
* 'insert' | 'delete', 'f1'..'f12', single chars ('a', 'b', '1', ...).
|
|
17
|
+
*/
|
|
18
|
+
export interface KeyEvent {
|
|
19
|
+
/** Raw bytes received from the client */
|
|
20
|
+
raw: Buffer;
|
|
21
|
+
/** UTF-8 string representation */
|
|
22
|
+
str: string;
|
|
23
|
+
/** Recognized key name, if any */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Ctrl modifier was held */
|
|
26
|
+
ctrl: boolean;
|
|
27
|
+
/** Shift modifier was held (best-effort for letter keys) */
|
|
28
|
+
shift: boolean;
|
|
29
|
+
/** Meta/Alt modifier was held */
|
|
30
|
+
meta: boolean;
|
|
31
|
+
/** Original escape sequence for unrecognized keys */
|
|
32
|
+
sequence?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Information about the requesting SSH client.
|
|
36
|
+
*/
|
|
37
|
+
export interface SshClientInfo {
|
|
38
|
+
/** Remote IP address */
|
|
39
|
+
ip: string;
|
|
40
|
+
/** Remote port */
|
|
41
|
+
port: number;
|
|
42
|
+
/** Address family ('IPv4' | 'IPv6') */
|
|
43
|
+
family: string;
|
|
44
|
+
/** Client software identifier (e.g. 'SSH-2.0-OpenSSH_9.0') */
|
|
45
|
+
identRaw: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Authentication request the user handler can accept or reject.
|
|
49
|
+
*
|
|
50
|
+
* Returning `true` accepts; returning `false` (or throwing) rejects.
|
|
51
|
+
*/
|
|
52
|
+
export type SshAuthHandler = ((req: SshAuthRequest) => boolean | Promise<boolean>) | true;
|
|
53
|
+
export interface SshAuthRequest {
|
|
54
|
+
/** Username supplied by the client */
|
|
55
|
+
username: string;
|
|
56
|
+
/** Auth method being attempted */
|
|
57
|
+
method: 'none' | 'password' | 'publickey' | 'keyboard-interactive' | 'hostbased';
|
|
58
|
+
/** Password, when method === 'password' */
|
|
59
|
+
password?: string;
|
|
60
|
+
/** Public key info, when method === 'publickey' */
|
|
61
|
+
publicKey?: {
|
|
62
|
+
algo: string;
|
|
63
|
+
data: Buffer;
|
|
64
|
+
};
|
|
65
|
+
/** Client info */
|
|
66
|
+
client: SshClientInfo;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* SSH authentication configuration. At least one method should be enabled.
|
|
70
|
+
*/
|
|
71
|
+
export interface SshAuthOptions {
|
|
72
|
+
/**
|
|
73
|
+
* Allow anonymous (no-auth) connections. Default: false.
|
|
74
|
+
* When true, the username sent by the client is preserved but no
|
|
75
|
+
* credential is required (terminal.shop-style).
|
|
76
|
+
*/
|
|
77
|
+
none?: boolean | SshAuthHandler;
|
|
78
|
+
/** Password verifier */
|
|
79
|
+
password?: SshAuthHandler;
|
|
80
|
+
/** Public key verifier */
|
|
81
|
+
publicKey?: SshAuthHandler;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Pseudo-TTY information for the session.
|
|
85
|
+
*/
|
|
86
|
+
export interface SshPtyInfo {
|
|
87
|
+
cols: number;
|
|
88
|
+
rows: number;
|
|
89
|
+
width: number;
|
|
90
|
+
height: number;
|
|
91
|
+
term: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Handler invoked once an authenticated client opens a shell or subsystem.
|
|
95
|
+
*
|
|
96
|
+
* The handler controls the session lifecycle — it should `await` something
|
|
97
|
+
* (e.g. `session.signal` aborting, or `session.keys` iteration) to keep the
|
|
98
|
+
* channel open. When the handler returns, the session is closed.
|
|
99
|
+
*/
|
|
100
|
+
export type SshSessionHandler = (session: SshSession) => void | Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* The high-level SSH session object passed to user handlers.
|
|
103
|
+
*
|
|
104
|
+
* Provides three layers of API:
|
|
105
|
+
* 1. Raw streams — `stdin`, `stdout`, `stderr`
|
|
106
|
+
* 2. Helpers — `write`, `clear`, `keys`, `onResize`
|
|
107
|
+
* 3. tuiuiu bridge — `tui` (lazy)
|
|
108
|
+
*
|
|
109
|
+
* The session is closed when the handler returns, when the client
|
|
110
|
+
* disconnects, or when `close()` is called.
|
|
111
|
+
*/
|
|
112
|
+
export interface SshSession {
|
|
113
|
+
/** Unique session id */
|
|
114
|
+
readonly id: string;
|
|
115
|
+
/** Authenticated username */
|
|
116
|
+
readonly user: string;
|
|
117
|
+
/**
|
|
118
|
+
* Auth method used by this session.
|
|
119
|
+
* 'none' = anonymous (public access).
|
|
120
|
+
* Use this in handlers to branch between public and private behavior.
|
|
121
|
+
*/
|
|
122
|
+
readonly authMethod: 'none' | 'password' | 'publickey';
|
|
123
|
+
/**
|
|
124
|
+
* Auth-method-specific data. Useful for identifying authenticated users
|
|
125
|
+
* (e.g. key fingerprint from publicKey auth).
|
|
126
|
+
*/
|
|
127
|
+
readonly authData: {
|
|
128
|
+
publicKey?: {
|
|
129
|
+
algo: string;
|
|
130
|
+
data: Buffer;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
/** Remote client info */
|
|
134
|
+
readonly client: SshClientInfo;
|
|
135
|
+
/** Environment variables the client requested (SetEnv) */
|
|
136
|
+
readonly env: Record<string, string>;
|
|
137
|
+
/** Pseudo-TTY info, or null if the client did not request a pty */
|
|
138
|
+
readonly pty: SshPtyInfo | null;
|
|
139
|
+
/** Convenience: current cols (or 80 if no pty) */
|
|
140
|
+
readonly cols: number;
|
|
141
|
+
/** Convenience: current rows (or 24 if no pty) */
|
|
142
|
+
readonly rows: number;
|
|
143
|
+
/** Convenience: current TERM (or 'xterm' if no pty) */
|
|
144
|
+
readonly term: string;
|
|
145
|
+
/** Raw stdin from the client (the pty input). */
|
|
146
|
+
readonly stdin: Readable;
|
|
147
|
+
/** Raw stdout to the client. */
|
|
148
|
+
readonly stdout: Writable;
|
|
149
|
+
/** Raw stderr to the client. */
|
|
150
|
+
readonly stderr: Writable;
|
|
151
|
+
/** Whether the client requested a 'shell' (interactive) vs an 'exec' (one-shot command). */
|
|
152
|
+
readonly kind: 'shell' | 'exec' | 'subsystem';
|
|
153
|
+
/** For 'exec' sessions: the command line. */
|
|
154
|
+
readonly command?: string;
|
|
155
|
+
/** For 'subsystem' sessions: the subsystem name. */
|
|
156
|
+
readonly subsystem?: string;
|
|
157
|
+
/** Aborts when the session closes (either side). */
|
|
158
|
+
readonly signal: AbortSignal;
|
|
159
|
+
/** Write text to stdout. Convenience for `stdout.write(text)`. */
|
|
160
|
+
write(text: string | Uint8Array): void;
|
|
161
|
+
/** Clear screen and home cursor (ANSI `\x1b[2J\x1b[H`). */
|
|
162
|
+
clear(): void;
|
|
163
|
+
/** Async iterable of parsed key events from stdin. */
|
|
164
|
+
readonly keys: AsyncIterable<KeyEvent>;
|
|
165
|
+
/** Register a window-resize handler. Fires with new cols/rows. */
|
|
166
|
+
onResize(handler: (cols: number, rows: number) => void): void;
|
|
167
|
+
/** Register a close handler. */
|
|
168
|
+
onClose(handler: () => void): void;
|
|
169
|
+
/** Close the session. Optional exit code (default 0). */
|
|
170
|
+
close(exitCode?: number): void;
|
|
171
|
+
/**
|
|
172
|
+
* Lazy TTY-compatible streams for use with tuiuiu.js `render()`.
|
|
173
|
+
* Returns `{ stdin, stdout }` where both wrap the raw streams with
|
|
174
|
+
* `isTTY = true`, `columns`, `rows`, and resize events.
|
|
175
|
+
*
|
|
176
|
+
* Throws if tuiuiu.js is not installed.
|
|
177
|
+
*/
|
|
178
|
+
readonly tui: {
|
|
179
|
+
stdin: TtyReadable;
|
|
180
|
+
stdout: TtyWritable;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Minimal TTY-like Readable surface (subset Node's process.stdin offers).
|
|
185
|
+
* Used by the tuiuiu bridge — declared here to avoid leaking ssh2 types.
|
|
186
|
+
*/
|
|
187
|
+
export interface TtyReadable extends Readable {
|
|
188
|
+
isTTY: true;
|
|
189
|
+
setRawMode?(mode: boolean): this;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Minimal TTY-like Writable surface.
|
|
193
|
+
*/
|
|
194
|
+
export interface TtyWritable extends Writable {
|
|
195
|
+
isTTY: true;
|
|
196
|
+
columns: number;
|
|
197
|
+
rows: number;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Host key — either a PEM/OpenSSH-formatted Buffer/string, or an object
|
|
201
|
+
* with key + passphrase for encrypted keys.
|
|
202
|
+
*/
|
|
203
|
+
export type SshHostKey = Buffer | string | {
|
|
204
|
+
key: Buffer | string;
|
|
205
|
+
passphrase?: Buffer | string;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* SSH adapter configuration.
|
|
209
|
+
*/
|
|
210
|
+
export interface SshAdapterOptions {
|
|
211
|
+
/** Port to listen on (typical: 2222 for dev, 22 needs root) */
|
|
212
|
+
port: number;
|
|
213
|
+
/** Host to bind to (default: '0.0.0.0') */
|
|
214
|
+
host?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Host private keys. If omitted or empty, an ephemeral RSA 2048 key is
|
|
217
|
+
* generated on `start()` — fine for dev, NOT for production (clients
|
|
218
|
+
* will see a key-changed warning each restart). For production, pass
|
|
219
|
+
* a stable key from disk.
|
|
220
|
+
*/
|
|
221
|
+
hostKeys?: SshHostKey[];
|
|
222
|
+
/** Banner sent to clients before authentication. */
|
|
223
|
+
banner?: string;
|
|
224
|
+
/** Server software ident (default: 'SSH-2.0-Raffel') */
|
|
225
|
+
ident?: string;
|
|
226
|
+
/**
|
|
227
|
+
* Authentication configuration. If omitted, `none` is enabled
|
|
228
|
+
* (anonymous access) — terminal.shop-style. Override for real auth.
|
|
229
|
+
*/
|
|
230
|
+
auth?: SshAuthOptions;
|
|
231
|
+
/**
|
|
232
|
+
* Session handler invoked once a client opens a shell.
|
|
233
|
+
* Required for the adapter to be useful.
|
|
234
|
+
*/
|
|
235
|
+
onSession: SshSessionHandler;
|
|
236
|
+
/**
|
|
237
|
+
* Handler for `exec` requests (e.g. `ssh host some-command`).
|
|
238
|
+
* If omitted, exec requests are rejected.
|
|
239
|
+
*/
|
|
240
|
+
onExec?: SshSessionHandler;
|
|
241
|
+
/**
|
|
242
|
+
* Handlers for named subsystems (e.g. SFTP would be 'sftp').
|
|
243
|
+
* If omitted, subsystem requests are rejected.
|
|
244
|
+
*/
|
|
245
|
+
subsystems?: Record<string, SshSessionHandler>;
|
|
246
|
+
/** Inbound connection filter — controls which source IPs may connect. */
|
|
247
|
+
filter?: ConnectionFilter;
|
|
248
|
+
/** Keep-alive interval (ms). Default: 30000. 0 disables. */
|
|
249
|
+
keepAliveInterval?: number;
|
|
250
|
+
/** Max failed keep-alive attempts before dropping. Default: 3. */
|
|
251
|
+
keepAliveMaxFailures?: number;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* SSH adapter handle.
|
|
255
|
+
*/
|
|
256
|
+
export interface SshAdapter {
|
|
257
|
+
/** Start the SSH server. */
|
|
258
|
+
start(): Promise<void>;
|
|
259
|
+
/** Stop the server and close all sessions. */
|
|
260
|
+
stop(): Promise<void>;
|
|
261
|
+
/** Number of currently active sessions. */
|
|
262
|
+
readonly sessionCount: number;
|
|
263
|
+
/** Bound port (after start). */
|
|
264
|
+
readonly port: number;
|
|
265
|
+
/** Bound host (after start). */
|
|
266
|
+
readonly host: string;
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=ssh-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-types.d.ts","sourceRoot":"","sources":["../../src/adapters/ssh-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Adapter — Types
|
|
3
|
+
*
|
|
4
|
+
* Public types for the SSH adapter. Requires `ssh2` (optional peer dep)
|
|
5
|
+
* at runtime. Types here are intentionally decoupled from ssh2's internal
|
|
6
|
+
* types so the public surface stays stable.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ssh-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-types.js","sourceRoot":"","sources":["../../src/adapters/ssh-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|