ai-remote 0.5.0 → 0.5.1
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/{cli-chunk-F2TSY3YW.mjs → cli-chunk-DGYNADUR.mjs} +1 -1
- package/dist/{cli-chunk-Q33YGIDO.mjs → cli-chunk-M5GGPPAC.mjs} +1 -1
- package/dist/{cli-chunk-OZG2CODR.mjs → cli-chunk-WBOYG4KJ.mjs} +1 -1
- package/dist/{cli-chunk-S2TWL5LF.mjs → cli-chunk-X2JMVOWL.mjs} +77 -20
- package/dist/{cli-copy-BOF44DWQ.mjs → cli-copy-ZBTICP7N.mjs} +1 -1
- package/dist/{cli-daemon-3BBFQCML.mjs → cli-daemon-M3KM2YHW.mjs} +233 -80
- package/dist/{cli-identities-ZILT4XCR.mjs → cli-identities-GBQWYF2O.mjs} +4 -4
- package/dist/{cli-shell-45XRTE7O.mjs → cli-shell-22PZYNSJ.mjs} +2 -2
- package/dist/{cli-window-ZKAXEHQV.mjs → cli-window-WLRFUKSW.mjs} +2 -2
- package/dist/cli.mjs +26 -22
- package/dist/protocols.d.ts +149 -15
- package/dist/protocols.js +16 -16
- package/package.json +1 -1
|
@@ -53,7 +53,7 @@ async function parsePrivateKey(text, comment = "") {
|
|
|
53
53
|
async function parseOpenSshKey(body, comment) {
|
|
54
54
|
const magic = new TextDecoder().decode(body.subarray(0, OPENSSH_MAGIC.length));
|
|
55
55
|
if (magic !== OPENSSH_MAGIC) throw new Error("this is not an OpenSSH private key");
|
|
56
|
-
const reader = new SshReader(body, OPENSSH_MAGIC.length);
|
|
56
|
+
const reader = new SshReader(body.slice(), OPENSSH_MAGIC.length);
|
|
57
57
|
const cipher = reader.string();
|
|
58
58
|
reader.string();
|
|
59
59
|
reader.stringBytes();
|
|
@@ -171,7 +171,7 @@ async function ecdsaIdentity(keyBlob, curve, point, d, comment) {
|
|
|
171
171
|
const x = point.subarray(1, 1 + spec.size);
|
|
172
172
|
const y = point.subarray(1 + spec.size, 1 + spec.size * 2);
|
|
173
173
|
const key = await importJwk(
|
|
174
|
-
{ kty: "EC", crv: spec.jwk, x: b64u(x), y: b64u(y), d: b64u(padStart(d, spec.size)) },
|
|
174
|
+
{ kty: "EC", crv: spec.jwk, x: b64u(x), y: b64u(y), d: b64u(padStart(d.slice(), spec.size)) },
|
|
175
175
|
{ name: "ECDSA", namedCurve: spec.jwk }
|
|
176
176
|
);
|
|
177
177
|
const algorithm = `ecdsa-sha2-${curve}`;
|
|
@@ -231,8 +231,8 @@ async function fromPkcs8(der, comment) {
|
|
|
231
231
|
const [name, spec] = curve;
|
|
232
232
|
const point = concatBytes(
|
|
233
233
|
new Uint8Array([4]),
|
|
234
|
-
padStart(from(jwk.x), spec.size),
|
|
235
|
-
padStart(from(jwk.y), spec.size)
|
|
234
|
+
padStart(from(jwk.x).slice(), spec.size),
|
|
235
|
+
padStart(from(jwk.y).slice(), spec.size)
|
|
236
236
|
);
|
|
237
237
|
return ecdsaIdentity(new Uint8Array(0), name, point, from(jwk.d), comment);
|
|
238
238
|
}
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
openWindow,
|
|
5
5
|
readCurrentDisplaySize,
|
|
6
6
|
runWindow
|
|
7
|
-
} from "./cli-chunk-
|
|
8
|
-
import "./cli-chunk-
|
|
7
|
+
} from "./cli-chunk-DGYNADUR.mjs";
|
|
8
|
+
import "./cli-chunk-WBOYG4KJ.mjs";
|
|
9
9
|
export {
|
|
10
10
|
detectCurrentDisplaySize,
|
|
11
11
|
nativeWindowAvailable,
|
package/dist/cli.mjs
CHANGED
|
@@ -13,12 +13,21 @@ import {
|
|
|
13
13
|
metaPath,
|
|
14
14
|
sessionName,
|
|
15
15
|
socketPath
|
|
16
|
-
} from "./cli-chunk-
|
|
16
|
+
} from "./cli-chunk-WBOYG4KJ.mjs";
|
|
17
17
|
|
|
18
18
|
// src/cli/cli.ts
|
|
19
19
|
import { resolve as resolvePath } from "node:path";
|
|
20
20
|
import { readFileSync as readFileSync2, openSync } from "node:fs";
|
|
21
21
|
|
|
22
|
+
// src/cli/target.ts
|
|
23
|
+
function splitTarget(target, fallbackPort) {
|
|
24
|
+
const stripped = target.replace(/^\w+:\/\//, "");
|
|
25
|
+
const at = stripped.lastIndexOf("@");
|
|
26
|
+
const account = at === -1 ? "" : stripped.slice(0, at);
|
|
27
|
+
const [host, port] = (at === -1 ? stripped : stripped.slice(at + 1)).split(":");
|
|
28
|
+
return { account, host, port: port ? Number(port) : fallbackPort };
|
|
29
|
+
}
|
|
30
|
+
|
|
22
31
|
// src/cli/prompt.ts
|
|
23
32
|
function canPrompt() {
|
|
24
33
|
return Boolean(process.stdin.isTTY) && !process.env.AI_REMOTE_NO_PROMPT;
|
|
@@ -312,11 +321,6 @@ var flag = (args, ...names) => {
|
|
|
312
321
|
return void 0;
|
|
313
322
|
};
|
|
314
323
|
var has = (args, ...names) => names.some((name) => args.flags[name] === true);
|
|
315
|
-
function splitTarget(target, fallbackPort) {
|
|
316
|
-
const stripped = target.replace(/^\w+:\/\//, "");
|
|
317
|
-
const [host, port] = stripped.split(":");
|
|
318
|
-
return { host, port: port ? Number(port) : fallbackPort };
|
|
319
|
-
}
|
|
320
324
|
var PORTS = { rdp: 3389, vnc: 5900, ssh: 22 };
|
|
321
325
|
function modeFor(args, target) {
|
|
322
326
|
if (has(args, "ssh", "ssh-only", "terminal")) return "ssh";
|
|
@@ -361,7 +365,7 @@ async function promptFor(host, port, username, note = "") {
|
|
|
361
365
|
}
|
|
362
366
|
function identityLoader(paths) {
|
|
363
367
|
return async () => {
|
|
364
|
-
const { loadIdentities } = await import("./cli-identities-
|
|
368
|
+
const { loadIdentities } = await import("./cli-identities-GBQWYF2O.mjs");
|
|
365
369
|
const { identities, skipped } = await loadIdentities(paths);
|
|
366
370
|
for (const note of skipped) console.log(`[ssh] skipped ${note}`);
|
|
367
371
|
console.log(identities.length ? `[ssh] keys: ${identities.map((identity) => identity.comment).join(", ")}` : "[ssh] no keys to offer");
|
|
@@ -430,13 +434,13 @@ async function tell(session, op, args = {}, timeoutMs) {
|
|
|
430
434
|
}
|
|
431
435
|
return result;
|
|
432
436
|
}
|
|
433
|
-
async function startSession(args, name, host, port, secret) {
|
|
437
|
+
async function startSession(args, name, host, port, secret, account = "") {
|
|
434
438
|
const mode = modeFor(args, `${host}:${port}`);
|
|
435
439
|
const explicitWidth = flag(args, "W", "width");
|
|
436
440
|
const explicitHeight = flag(args, "H", "height");
|
|
437
441
|
let fullscreenSize = null;
|
|
438
442
|
if (mode === "rdp" && has(args, "fullscreen") && (!explicitWidth || !explicitHeight)) {
|
|
439
|
-
const { detectCurrentDisplaySize } = await import("./cli-window-
|
|
443
|
+
const { detectCurrentDisplaySize } = await import("./cli-window-WLRFUKSW.mjs");
|
|
440
444
|
const display = await detectCurrentDisplaySize();
|
|
441
445
|
if (display) fullscreenSize = fullscreenRdpSize(display, has(args, "side-panel"));
|
|
442
446
|
}
|
|
@@ -453,7 +457,7 @@ async function startSession(args, name, host, port, secret) {
|
|
|
453
457
|
"--name",
|
|
454
458
|
name,
|
|
455
459
|
"-u",
|
|
456
|
-
flag(args, "u", "user") ??
|
|
460
|
+
flag(args, "u", "user") ?? account,
|
|
457
461
|
"-d",
|
|
458
462
|
flag(args, "d", "domain") ?? "",
|
|
459
463
|
"-s",
|
|
@@ -463,7 +467,7 @@ async function startSession(args, name, host, port, secret) {
|
|
|
463
467
|
"-H",
|
|
464
468
|
height,
|
|
465
469
|
"--ssh-user",
|
|
466
|
-
flag(args, "ssh-user") ?? flag(args, "u", "user") ??
|
|
470
|
+
flag(args, "ssh-user") ?? flag(args, "u", "user") ?? account,
|
|
467
471
|
// In a terminal session the target port is the SSH port; there is no other.
|
|
468
472
|
"--ssh-port",
|
|
469
473
|
flag(args, "ssh-port") ?? (mode === "ssh" ? String(port) : "22"),
|
|
@@ -559,7 +563,7 @@ async function main() {
|
|
|
559
563
|
}
|
|
560
564
|
const json = has(args, "json");
|
|
561
565
|
if (args.command === "__display-size") {
|
|
562
|
-
const { readCurrentDisplaySize } = await import("./cli-window-
|
|
566
|
+
const { readCurrentDisplaySize } = await import("./cli-window-WLRFUKSW.mjs");
|
|
563
567
|
const size = await readCurrentDisplaySize();
|
|
564
568
|
if (size) process.stdout.write(`${JSON.stringify(size)}
|
|
565
569
|
`);
|
|
@@ -568,7 +572,7 @@ async function main() {
|
|
|
568
572
|
if (args.command === "__session") {
|
|
569
573
|
const mode = modeFor(args, args.rest[0]);
|
|
570
574
|
const { host, port } = splitTarget(args.rest[0] ?? "", defaultPort(mode));
|
|
571
|
-
const { runDaemon } = await import("./cli-daemon-
|
|
575
|
+
const { runDaemon } = await import("./cli-daemon-M3KM2YHW.mjs");
|
|
572
576
|
await runDaemon({
|
|
573
577
|
name: sessionName(host, port, flag(args, "name", "session")),
|
|
574
578
|
host,
|
|
@@ -601,7 +605,7 @@ async function main() {
|
|
|
601
605
|
return;
|
|
602
606
|
}
|
|
603
607
|
if (args.command === "__window") {
|
|
604
|
-
const { runWindow } = await import("./cli-window-
|
|
608
|
+
const { runWindow } = await import("./cli-window-WLRFUKSW.mjs");
|
|
605
609
|
await runWindow(process.argv.slice(3));
|
|
606
610
|
return;
|
|
607
611
|
}
|
|
@@ -653,11 +657,11 @@ Saved, nothing open (\`${NAME} open <host>\` needs no password):
|
|
|
653
657
|
throw new CliError(`--keys takes "adapt" or "literal", not "${keys}".`, 12);
|
|
654
658
|
}
|
|
655
659
|
const mode = modeFor(args, target);
|
|
656
|
-
const { host, port } = splitTarget(target, defaultPort(mode));
|
|
660
|
+
const { account: targetAccount, host, port } = splitTarget(target, defaultPort(mode));
|
|
657
661
|
const asked = flag(args, "session", "name");
|
|
658
662
|
const base = sessionName(host, port, asked);
|
|
659
663
|
const name2 = has(args, "no-reuse") && !asked ? freeName(base, liveSessions().map((meta) => meta.name)) : base;
|
|
660
|
-
const account = flag(args, "u", "user") ??
|
|
664
|
+
const account = flag(args, "u", "user") ?? targetAccount;
|
|
661
665
|
const prompts = prompting(args);
|
|
662
666
|
let secret = await passwordFor(host, port, account);
|
|
663
667
|
let prompted = false;
|
|
@@ -669,7 +673,7 @@ Saved, nothing open (\`${NAME} open <host>\` needs no password):
|
|
|
669
673
|
const reused = Boolean(status);
|
|
670
674
|
if (!status) {
|
|
671
675
|
try {
|
|
672
|
-
status = await startSession(args, name2, host, port, secret);
|
|
676
|
+
status = await startSession(args, name2, host, port, secret, account);
|
|
673
677
|
} catch (error) {
|
|
674
678
|
const refused = error instanceof CliError && error.code === 11;
|
|
675
679
|
if (!refused || prompted || !prompts) throw error;
|
|
@@ -683,7 +687,7 @@ Saved, nothing open (\`${NAME} open <host>\` needs no password):
|
|
|
683
687
|
cleanup(name2);
|
|
684
688
|
secret = typed;
|
|
685
689
|
prompted = true;
|
|
686
|
-
status = await startSession(args, name2, host, port, secret);
|
|
690
|
+
status = await startSession(args, name2, host, port, secret, account);
|
|
687
691
|
}
|
|
688
692
|
}
|
|
689
693
|
const saved = has(args, "save") && secret ? await keepSecret(host, port, account, secret) : null;
|
|
@@ -983,7 +987,7 @@ function report(json, command, summary) {
|
|
|
983
987
|
`);
|
|
984
988
|
}
|
|
985
989
|
async function sshLogin(args, session, what) {
|
|
986
|
-
const { bareUsername } = await import("./cli-shell-
|
|
990
|
+
const { bareUsername } = await import("./cli-shell-22PZYNSJ.mjs");
|
|
987
991
|
const username = bareUsername(flag(args, "ssh-user") ?? session.sshUser ?? "");
|
|
988
992
|
if (!username) {
|
|
989
993
|
throw new CliError(
|
|
@@ -991,7 +995,7 @@ async function sshLogin(args, session, what) {
|
|
|
991
995
|
12
|
|
992
996
|
);
|
|
993
997
|
}
|
|
994
|
-
const { loadIdentities } = await import("./cli-identities-
|
|
998
|
+
const { loadIdentities } = await import("./cli-identities-GBQWYF2O.mjs");
|
|
995
999
|
const { identities, skipped } = await loadIdentities(args.identities);
|
|
996
1000
|
const port = Number(flag(args, "ssh-port") ?? session.sshPort ?? 22);
|
|
997
1001
|
let password2 = await passwordFor(session.host, port, username);
|
|
@@ -1065,7 +1069,7 @@ async function copyFiles(args, json) {
|
|
|
1065
1069
|
upload,
|
|
1066
1070
|
walkLocal,
|
|
1067
1071
|
walkRemote
|
|
1068
|
-
} = await import("./cli-copy-
|
|
1072
|
+
} = await import("./cli-copy-ZBTICP7N.mjs");
|
|
1069
1073
|
const from = resolveEndpoint(args, parseEndpoint(args.rest[0]));
|
|
1070
1074
|
const to = resolveEndpoint(args, parseEndpoint(args.rest[1]));
|
|
1071
1075
|
if (!from.endpoint.remote && !to.endpoint.remote) {
|
|
@@ -1143,7 +1147,7 @@ async function copyFiles(args, json) {
|
|
|
1143
1147
|
}
|
|
1144
1148
|
}
|
|
1145
1149
|
async function interactiveShell(args, session) {
|
|
1146
|
-
const { Shell } = await import("./cli-shell-
|
|
1150
|
+
const { Shell } = await import("./cli-shell-22PZYNSJ.mjs");
|
|
1147
1151
|
const login = await sshLogin(args, session, "a terminal");
|
|
1148
1152
|
const { username, port, identities } = login;
|
|
1149
1153
|
const prompts = prompting(args);
|
package/dist/protocols.d.ts
CHANGED
|
@@ -139,6 +139,14 @@ interface ScrollDelta {
|
|
|
139
139
|
x: number;
|
|
140
140
|
y: number;
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* What the metrics rail instruments. A real WebSocket in the browser; in the
|
|
144
|
+
* CLI, a shim with the same surface over a TCP socket straight at the host.
|
|
145
|
+
*/
|
|
146
|
+
interface InstrumentableSocket {
|
|
147
|
+
readonly readyState: number;
|
|
148
|
+
addEventListener(type: string, listener: (event: any) => void): void;
|
|
149
|
+
}
|
|
142
150
|
/**
|
|
143
151
|
* A live session. Both drivers expose this, so the AI pane's screen tool and
|
|
144
152
|
* the toolbar never have to ask which protocol they are driving.
|
|
@@ -157,7 +165,7 @@ export interface RemoteSession extends EventTarget {
|
|
|
157
165
|
/** RFB compression level. RDP ignores it. */
|
|
158
166
|
compressionLevel?: number;
|
|
159
167
|
/** The transport the metrics rail instruments. Can appear a tick after construction. */
|
|
160
|
-
readonly socket?:
|
|
168
|
+
readonly socket?: InstrumentableSocket | null;
|
|
161
169
|
readonly screenGeometry: ScreenGeometry;
|
|
162
170
|
movePointer(x: number, y: number): boolean;
|
|
163
171
|
clickPointer(x: number, y: number, button?: PointerButton): boolean;
|
|
@@ -245,6 +253,45 @@ export interface ProtocolDriver {
|
|
|
245
253
|
/** Protocol-specific wording for a close, or null to fall back to the shared text. */
|
|
246
254
|
describeDisconnect(context: DisconnectContext): string | null;
|
|
247
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Signing in with a key instead of a password.
|
|
258
|
+
*
|
|
259
|
+
* An identity is a public key blob, the algorithm name that goes with it, and
|
|
260
|
+
* something that can sign. What does the signing is deliberately behind a
|
|
261
|
+
* function: a key read off disk signs with Web Crypto, and a key held by
|
|
262
|
+
* ssh-agent signs by asking the agent -- the session cannot tell the two apart
|
|
263
|
+
* and does not need to.
|
|
264
|
+
*
|
|
265
|
+
* The parser here reads the format `ssh-keygen` writes by default, which no
|
|
266
|
+
* runtime can parse on its own: OpenSSH's own container rather than PKCS#8.
|
|
267
|
+
* Only unencrypted keys are read. A key with a passphrase would need bcrypt
|
|
268
|
+
* and a prompt, and the answer to a passphrase is ssh-agent, which is already
|
|
269
|
+
* holding the decrypted key.
|
|
270
|
+
*/
|
|
271
|
+
/** One key that can sign for a user, however it happens to be held. */
|
|
272
|
+
interface SshIdentity {
|
|
273
|
+
/** The public key type, e.g. `ssh-ed25519`. */
|
|
274
|
+
readonly keyType: string;
|
|
275
|
+
/** The public key, in the wire format the host expects. */
|
|
276
|
+
readonly keyBlob: Uint8Array;
|
|
277
|
+
/** Where it came from, for logs and error messages. */
|
|
278
|
+
readonly comment: string;
|
|
279
|
+
/**
|
|
280
|
+
* Signature algorithms to offer, best first. RSA keys sign under several,
|
|
281
|
+
* and a host will say which of them it is willing to take.
|
|
282
|
+
*/
|
|
283
|
+
readonly algorithms: readonly string[];
|
|
284
|
+
/** The full signature blob (algorithm name and signature) over `data`. */
|
|
285
|
+
sign(data: Uint8Array, algorithm: string): Promise<Uint8Array>;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Read a private key file.
|
|
289
|
+
*
|
|
290
|
+
* Returns one identity, or throws with the reason a human can act on -- which
|
|
291
|
+
* for the common failure is "this key has a passphrase, so let ssh-agent hold
|
|
292
|
+
* it" rather than a decoder error.
|
|
293
|
+
*/
|
|
294
|
+
declare function parsePrivateKey(text: string, comment?: string): Promise<SshIdentity>;
|
|
248
295
|
export declare const DEFAULT_PORT = 22;
|
|
249
296
|
export declare const COMMAND_MAX_MS: number;
|
|
250
297
|
/**
|
|
@@ -253,9 +300,88 @@ export declare const COMMAND_MAX_MS: number;
|
|
|
253
300
|
* Each shell gets its own, because none of the three agree on how to print a
|
|
254
301
|
* string, run a command and read back its exit status.
|
|
255
302
|
*/
|
|
256
|
-
export declare function frameCommand(family:
|
|
303
|
+
export declare function frameCommand(family: string, command: string, id: string): string;
|
|
304
|
+
/** What runCommand resolves with. */
|
|
305
|
+
export interface CommandResult {
|
|
306
|
+
output: string;
|
|
307
|
+
exitStatus: number | null;
|
|
308
|
+
exitSignal?: string;
|
|
309
|
+
timedOut?: boolean;
|
|
310
|
+
started?: boolean;
|
|
311
|
+
reason?: string;
|
|
312
|
+
durationMs: number;
|
|
313
|
+
}
|
|
314
|
+
/** A tool command's output framing, hidden from the screen while it runs. */
|
|
315
|
+
interface DisplayFilter {
|
|
316
|
+
begin: string;
|
|
317
|
+
end: string;
|
|
318
|
+
stage: 'before' | 'inside' | 'closing';
|
|
319
|
+
pending: string;
|
|
320
|
+
}
|
|
321
|
+
/** What a caller can ask of an SSH session. */
|
|
322
|
+
export interface SshSessionOptions {
|
|
323
|
+
username?: string;
|
|
324
|
+
password?: string;
|
|
325
|
+
identities?: SshIdentity[] | (() => Promise<SshIdentity[]>);
|
|
326
|
+
preferredShell?: 'powershell';
|
|
327
|
+
/** Run a subsystem (e.g. 'sftp') rather than a shell. */
|
|
328
|
+
subsystem?: string;
|
|
329
|
+
columns?: number;
|
|
330
|
+
rows?: number;
|
|
331
|
+
hostLabel?: string;
|
|
332
|
+
log?: (step: string, detail?: unknown) => void;
|
|
333
|
+
verifyHost?: (info: any) => Promise<boolean> | boolean;
|
|
334
|
+
openTransport?: ((url: string) => any) | null;
|
|
335
|
+
requestInput?: (prompt: any) => Promise<string>;
|
|
336
|
+
}
|
|
257
337
|
export declare class SshSession extends EventTarget {
|
|
258
338
|
#private;
|
|
339
|
+
private readonly options;
|
|
340
|
+
private readonly username;
|
|
341
|
+
private password;
|
|
342
|
+
/**
|
|
343
|
+
* Keys to sign in with, if any. A function rather than a list is allowed
|
|
344
|
+
* because reading keys off a disk -- or asking an agent for them -- is work
|
|
345
|
+
* a session that never needs them should not do.
|
|
346
|
+
*/
|
|
347
|
+
/** Replaced with the resolved list the first time it is read. */
|
|
348
|
+
private identities;
|
|
349
|
+
private readonly requestInput;
|
|
350
|
+
/** Whether there is anybody to ask; see the constructor. */
|
|
351
|
+
private readonly canAsk;
|
|
352
|
+
private columns;
|
|
353
|
+
private rows;
|
|
354
|
+
/** A subsystem to run instead of a shell, e.g. 'sftp'. */
|
|
355
|
+
private readonly subsystem;
|
|
356
|
+
private channelId;
|
|
357
|
+
private remoteChannelId;
|
|
358
|
+
private remoteWindow;
|
|
359
|
+
private remoteMaxPacket;
|
|
360
|
+
private localWindow;
|
|
361
|
+
private pendingWrites;
|
|
362
|
+
private shellOpen;
|
|
363
|
+
private commandInFlight;
|
|
364
|
+
/** Set while a tool command runs, to keep its framing off the screen. */
|
|
365
|
+
displayFilter: DisplayFilter | null;
|
|
366
|
+
/** True only after the requested interactive shell is ready for commands. */
|
|
367
|
+
private readySignaled;
|
|
368
|
+
private powerShellAttempted;
|
|
369
|
+
private powerShellTimer;
|
|
370
|
+
/** '', 'posix', 'cmd' or 'powershell'; learned from the prompt. */
|
|
371
|
+
private shellFamily;
|
|
372
|
+
private promptTail;
|
|
373
|
+
private exitStatus;
|
|
374
|
+
private exitSignal?;
|
|
375
|
+
private authMethods;
|
|
376
|
+
/** Which keys were offered and refused, for the message if nothing works. */
|
|
377
|
+
private triedKeys;
|
|
378
|
+
/** Set once the host has said no to the stored password. */
|
|
379
|
+
private passwordRejected;
|
|
380
|
+
private closed;
|
|
381
|
+
private waiters;
|
|
382
|
+
private readonly transport;
|
|
383
|
+
private fingerprint?;
|
|
384
|
+
private lastMessage?;
|
|
259
385
|
/**
|
|
260
386
|
* @param {string} url gateway WebSocket URL
|
|
261
387
|
* @param {object} options
|
|
@@ -268,11 +394,11 @@ export declare class SshSession extends EventTarget {
|
|
|
268
394
|
* @param {(info: object) => Promise<boolean>} [options.verifyHost]
|
|
269
395
|
* @param {(prompt: object) => Promise<string>} [options.requestInput]
|
|
270
396
|
*/
|
|
271
|
-
constructor(url: string, options?:
|
|
397
|
+
constructor(url: string, options?: SshSessionOptions);
|
|
272
398
|
connect(): void;
|
|
273
399
|
disconnect(): void;
|
|
274
400
|
/** Send keystrokes, or anything else the terminal produces, to the shell. */
|
|
275
|
-
write(data: Uint8Array): void;
|
|
401
|
+
write(data: Uint8Array | string): void;
|
|
276
402
|
/**
|
|
277
403
|
* Run one command in this shell and return what it printed.
|
|
278
404
|
*
|
|
@@ -299,12 +425,20 @@ export declare class SshSession extends EventTarget {
|
|
|
299
425
|
/** Tell the shell its window changed, so full-screen programs redraw. */
|
|
300
426
|
resize(columns: number, rows: number): void;
|
|
301
427
|
}
|
|
428
|
+
import { Terminal } from '@xterm/xterm';
|
|
302
429
|
export declare class SshTerminal {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
430
|
+
private readonly container;
|
|
431
|
+
readonly terminal: Terminal;
|
|
432
|
+
private readonly fitAddon;
|
|
433
|
+
private readonly observer;
|
|
434
|
+
/** Where keystrokes go; readLine swaps it out while it owns the line. */
|
|
435
|
+
private dataHandler;
|
|
436
|
+
private fitting;
|
|
437
|
+
constructor(container: HTMLElement);
|
|
438
|
+
get columns(): number;
|
|
439
|
+
get rows(): number;
|
|
440
|
+
onData(handler: ((data: string) => void) | null): void;
|
|
441
|
+
onResize(handler: (cols: number, rows: number) => void): void;
|
|
308
442
|
write(data: Uint8Array): void;
|
|
309
443
|
/** Gateway-side notices, kept visually apart from what the host prints. */
|
|
310
444
|
notice(text: string, tone?: string): void;
|
|
@@ -329,20 +463,20 @@ export declare class SshTerminal {
|
|
|
329
463
|
fit(): void;
|
|
330
464
|
/** The grid the host is being told about, for a status line or a log. */
|
|
331
465
|
get geometry(): {
|
|
332
|
-
columns:
|
|
333
|
-
rows:
|
|
334
|
-
fontSize:
|
|
466
|
+
columns: number;
|
|
467
|
+
rows: number;
|
|
468
|
+
fontSize: number;
|
|
335
469
|
};
|
|
336
|
-
get selection():
|
|
470
|
+
get selection(): string;
|
|
337
471
|
/**
|
|
338
472
|
* Read one line from the user, for a password or a one-time code the host
|
|
339
473
|
* asked for during authentication. The shell is not open yet, so the
|
|
340
474
|
* terminal is free to be a prompt.
|
|
341
475
|
*/
|
|
342
476
|
readLine({ prompt, echo }?: {
|
|
343
|
-
echo?: boolean;
|
|
344
477
|
prompt?: string;
|
|
345
|
-
|
|
478
|
+
echo?: boolean;
|
|
479
|
+
}): Promise<string>;
|
|
346
480
|
destroy(): void;
|
|
347
481
|
}
|
|
348
482
|
export declare const DRIVERS: Record<RemoteProtocol, ProtocolDriver>;
|