dsh-over-ssh 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +119 -2
- package/agents/agent-manifest.json +20 -0
- package/agents/linux-amd64/dsh-over-ssh-agent +0 -0
- package/agents/linux-arm64/dsh-over-ssh-agent +0 -0
- package/cordis.patch.yml +84 -0
- package/lib/client.js +6611 -0
- package/lib/file-references.js +366 -0
- package/lib/fs.js +1368 -0
- package/lib/index.js +19034 -0
- package/lib/local-bridge-refs.js +16 -0
- package/lib/local-bridge.js +16 -0
- package/lib/terminal-wrapper.js +294 -0
- package/lib/types/src/client/controls.d.ts +131 -0
- package/lib/types/src/client/core/card-focus-trap.d.ts +45 -0
- package/lib/types/src/client/core/controls.d.ts +164 -0
- package/lib/types/src/client/core/latest.d.ts +48 -0
- package/lib/types/src/client/core/locale.d.ts +38 -0
- package/lib/types/src/client/core/message.d.ts +37 -0
- package/lib/types/src/client/core/panel-model.d.ts +134 -0
- package/lib/types/src/client/core/portal.d.ts +266 -0
- package/lib/types/src/client/core/remote.d.ts +84 -0
- package/lib/types/src/client/core/styles.d.ts +458 -0
- package/lib/types/src/client/file-tree-io.d.ts +19 -0
- package/lib/types/src/client/file-tree.d.ts +271 -0
- package/lib/types/src/client/flows/directory-browser.d.ts +587 -0
- package/lib/types/src/client/flows/session-directory.d.ts +415 -0
- package/lib/types/src/client/flows/workspace-directory-flow.d.ts +480 -0
- package/lib/types/src/client/index.d.ts +49 -0
- package/lib/types/src/client/locale.d.ts +31 -0
- package/lib/types/src/client/panel-model.d.ts +37 -0
- package/lib/types/src/client/panel.d.ts +77 -0
- package/lib/types/src/client/roots/connection-test.d.ts +69 -0
- package/lib/types/src/client/roots/roots-panel-state.d.ts +307 -0
- package/lib/types/src/client/roots/roots-panel-view.d.ts +280 -0
- package/lib/types/src/client/roots/roots-panel.d.ts +364 -0
- package/lib/types/src/client/roots/transfer-panel-view.d.ts +35 -0
- package/lib/types/src/client/roots/transfer-panel.d.ts +241 -0
- package/lib/types/src/client/roots/transfer-progress.d.ts +67 -0
- package/lib/types/src/client/roots-panel-view.d.ts +236 -0
- package/lib/types/src/client/roots-panel.d.ts +347 -0
- package/lib/types/src/client/session/session-panel-view.d.ts +336 -0
- package/lib/types/src/client/session/session-panel.d.ts +322 -0
- package/lib/types/src/client/session/session-remote-mark.d.ts +110 -0
- package/lib/types/src/client/session/session-row-actions.d.ts +398 -0
- package/lib/types/src/client/session-panel.d.ts +152 -0
- package/lib/types/src/client/styles.d.ts +252 -0
- package/lib/types/src/client/workspace-directory-flow.d.ts +342 -0
- package/lib/types/src/config.d.ts +312 -0
- package/lib/types/src/file-references.d.ts +25 -0
- package/lib/types/src/fs.d.ts +46 -0
- package/lib/types/src/host/app/backend.d.ts +170 -0
- package/lib/types/src/host/app/recycle-bin/recycle-bin-contract.d.ts +247 -0
- package/lib/types/src/host/app/recycle-bin/recycle-bin-move.d.ts +18 -0
- package/lib/types/src/host/app/recycle-bin/recycle-bin-service.d.ts +45 -0
- package/lib/types/src/host/app/recycle-bin/recycle-bin-world.d.ts +38 -0
- package/lib/types/src/host/app/recycle-bin-contract.d.ts +215 -0
- package/lib/types/src/host/app/recycle-bin-move.d.ts +18 -0
- package/lib/types/src/host/app/recycle-bin-service.d.ts +45 -0
- package/lib/types/src/host/app/recycle-bin-world.d.ts +35 -0
- package/lib/types/src/host/app/roots/roots-api-connections.d.ts +49 -0
- package/lib/types/src/host/app/roots/roots-api-contract.d.ts +369 -0
- package/lib/types/src/host/app/roots/roots-api-directories.d.ts +13 -0
- package/lib/types/src/host/app/roots/roots-api-http.d.ts +77 -0
- package/lib/types/src/host/app/roots/roots-api-long-poll.d.ts +130 -0
- package/lib/types/src/host/app/roots/roots-api-projections.d.ts +102 -0
- package/lib/types/src/host/app/roots/roots-api-roots.d.ts +13 -0
- package/lib/types/src/host/app/roots/roots-api-state.d.ts +22 -0
- package/lib/types/src/host/app/roots/roots-api-transfers.d.ts +26 -0
- package/lib/types/src/host/app/roots/roots-api.d.ts +55 -0
- package/lib/types/src/host/app/roots/user-roots.d.ts +552 -0
- package/lib/types/src/host/app/roots-api-connections.d.ts +49 -0
- package/lib/types/src/host/app/roots-api-contract.d.ts +339 -0
- package/lib/types/src/host/app/roots-api-directories.d.ts +13 -0
- package/lib/types/src/host/app/roots-api-http.d.ts +77 -0
- package/lib/types/src/host/app/roots-api-projections.d.ts +102 -0
- package/lib/types/src/host/app/roots-api-roots.d.ts +13 -0
- package/lib/types/src/host/app/roots-api-state.d.ts +22 -0
- package/lib/types/src/host/app/roots-api-support.d.ts +182 -0
- package/lib/types/src/host/app/roots-api-transfers.d.ts +13 -0
- package/lib/types/src/host/app/roots-api.d.ts +55 -0
- package/lib/types/src/host/app/routed-fs.d.ts +239 -0
- package/lib/types/src/host/app/serialize.d.ts +37 -0
- package/lib/types/src/host/app/session-admin/session-admin-context.d.ts +36 -0
- package/lib/types/src/host/app/session-admin/session-admin-contract.d.ts +221 -0
- package/lib/types/src/host/app/session-admin/session-admin-delete.d.ts +34 -0
- package/lib/types/src/host/app/session-admin/session-admin-service.d.ts +40 -0
- package/lib/types/src/host/app/session-admin-context.d.ts +36 -0
- package/lib/types/src/host/app/session-admin-contract.d.ts +214 -0
- package/lib/types/src/host/app/session-admin-delete.d.ts +34 -0
- package/lib/types/src/host/app/session-admin-service.d.ts +38 -0
- package/lib/types/src/host/app/takeover/takeover-plan.d.ts +227 -0
- package/lib/types/src/host/app/takeover/takeover-rows.d.ts +55 -0
- package/lib/types/src/host/app/transport/transport-selector.d.ts +98 -0
- package/lib/types/src/host/app/transport/transport-service.d.ts +82 -0
- package/lib/types/src/host/app/transport-selector.d.ts +98 -0
- package/lib/types/src/host/app/transport-service.d.ts +75 -0
- package/lib/types/src/host/app/user-roots.d.ts +461 -0
- package/lib/types/src/host/domain/bin-location.d.ts +79 -0
- package/lib/types/src/host/domain/capability.d.ts +78 -0
- package/lib/types/src/host/domain/connection.d.ts +95 -0
- package/lib/types/src/host/domain/errors.d.ts +55 -0
- package/lib/types/src/host/domain/glob-pattern.d.ts +62 -0
- package/lib/types/src/host/domain/literal-text.d.ts +63 -0
- package/lib/types/src/host/domain/path-grammar.d.ts +84 -0
- package/lib/types/src/host/domain/recycle-bin.d.ts +337 -0
- package/lib/types/src/host/domain/root.d.ts +74 -0
- package/lib/types/src/host/domain/roots/bin-location.d.ts +91 -0
- package/lib/types/src/host/domain/roots/connection.d.ts +106 -0
- package/lib/types/src/host/domain/roots/root.d.ts +108 -0
- package/lib/types/src/host/domain/roots/route-table.d.ts +102 -0
- package/lib/types/src/host/domain/roots/session-roots.d.ts +151 -0
- package/lib/types/src/host/domain/roots/ssh-config.d.ts +73 -0
- package/lib/types/src/host/domain/route-table.d.ts +80 -0
- package/lib/types/src/host/domain/session/session-admin.d.ts +345 -0
- package/lib/types/src/host/domain/session/terminal-target.d.ts +136 -0
- package/lib/types/src/host/domain/session-admin.d.ts +330 -0
- package/lib/types/src/host/domain/shell.d.ts +47 -0
- package/lib/types/src/host/domain/ssh-config.d.ts +73 -0
- package/lib/types/src/host/domain/terminal-target.d.ts +132 -0
- package/lib/types/src/host/domain/tool-requests.d.ts +369 -0
- package/lib/types/src/host/domain/transfer/recycle-bin.d.ts +337 -0
- package/lib/types/src/host/domain/transfer/transfer.d.ts +260 -0
- package/lib/types/src/host/domain/transfer.d.ts +260 -0
- package/lib/types/src/host/infra/backend/local-backend.d.ts +84 -0
- package/lib/types/src/host/infra/backend/local-version.d.ts +43 -0
- package/lib/types/src/host/infra/backend/platform-local-backend.d.ts +89 -0
- package/lib/types/src/host/infra/backend/remote-backend.d.ts +239 -0
- package/lib/types/src/host/infra/cache/lru.d.ts +52 -0
- package/lib/types/src/host/infra/cache/versioned.d.ts +77 -0
- package/lib/types/src/host/infra/temp-name.d.ts +19 -0
- package/lib/types/src/host/infra/transport/agent/agent-installer.d.ts +121 -0
- package/lib/types/src/host/infra/transport/agent/agent-protocol-client.d.ts +132 -0
- package/lib/types/src/host/infra/transport/agent/agent-protocol-codec.d.ts +140 -0
- package/lib/types/src/host/infra/transport/agent/agent-protocol-errors.d.ts +41 -0
- package/lib/types/src/host/infra/transport/agent/agent-protocol-frames.d.ts +197 -0
- package/lib/types/src/host/infra/transport/agent/agent-protocol-types.d.ts +564 -0
- package/lib/types/src/host/infra/transport/agent/agent-transport.d.ts +418 -0
- package/lib/types/src/host/infra/transport/agent-installer.d.ts +121 -0
- package/lib/types/src/host/infra/transport/agent-protocol-client.d.ts +123 -0
- package/lib/types/src/host/infra/transport/agent-protocol-codec.d.ts +131 -0
- package/lib/types/src/host/infra/transport/agent-protocol-errors.d.ts +41 -0
- package/lib/types/src/host/infra/transport/agent-protocol-frames.d.ts +197 -0
- package/lib/types/src/host/infra/transport/agent-protocol-types.d.ts +509 -0
- package/lib/types/src/host/infra/transport/agent-transport.d.ts +353 -0
- package/lib/types/src/host/infra/transport/alias-transport.d.ts +206 -0
- package/lib/types/src/host/infra/transport/askpass-fs.d.ts +20 -0
- package/lib/types/src/host/infra/transport/askpass.d.ts +133 -0
- package/lib/types/src/host/infra/transport/command-pool.d.ts +61 -0
- package/lib/types/src/host/infra/transport/fs-commands.d.ts +140 -0
- package/lib/types/src/host/infra/transport/git-status-route.d.ts +63 -0
- package/lib/types/src/host/infra/transport/git-status.d.ts +101 -0
- package/lib/types/src/host/infra/transport/node-spawn.d.ts +26 -0
- package/lib/types/src/host/infra/transport/session-window.d.ts +51 -0
- package/lib/types/src/host/infra/transport/shell-quote.d.ts +59 -0
- package/lib/types/src/host/infra/transport/ssh/alias-transport.d.ts +206 -0
- package/lib/types/src/host/infra/transport/ssh/askpass-fs.d.ts +20 -0
- package/lib/types/src/host/infra/transport/ssh/askpass.d.ts +133 -0
- package/lib/types/src/host/infra/transport/ssh/shell-quote.d.ts +62 -0
- package/lib/types/src/host/infra/transport/ssh/ssh-argv.d.ts +43 -0
- package/lib/types/src/host/infra/transport/ssh/ssh2-transport.d.ts +328 -0
- package/lib/types/src/host/infra/transport/ssh-argv.d.ts +43 -0
- package/lib/types/src/host/infra/transport/ssh2-transport.d.ts +302 -0
- package/lib/types/src/host/infra/transport/transport-base.d.ts +34 -0
- package/lib/types/src/host/infra/transport/transport.d.ts +527 -0
- package/lib/types/src/host/integration/agent/agent-install-io.d.ts +33 -0
- package/lib/types/src/host/integration/agent/agent-preflight.d.ts +56 -0
- package/lib/types/src/host/integration/agent/askpass-registry.d.ts +66 -0
- package/lib/types/src/host/integration/agent-install-io.d.ts +33 -0
- package/lib/types/src/host/integration/agent-preflight.d.ts +56 -0
- package/lib/types/src/host/integration/anchor-directory.d.ts +56 -0
- package/lib/types/src/host/integration/askpass-registry.d.ts +59 -0
- package/lib/types/src/host/integration/bin-root-resolver.d.ts +81 -0
- package/lib/types/src/host/integration/connection-test.d.ts +73 -0
- package/lib/types/src/host/integration/file-reference-provider.d.ts +115 -0
- package/lib/types/src/host/integration/fs/file-reference-provider.d.ts +142 -0
- package/lib/types/src/host/integration/fs/fs-provider.d.ts +368 -0
- package/lib/types/src/host/integration/fs/git-status-wiring.d.ts +21 -0
- package/lib/types/src/host/integration/fs/platform-errors.d.ts +94 -0
- package/lib/types/src/host/integration/fs/remote-file-tools.d.ts +369 -0
- package/lib/types/src/host/integration/fs/remote-index.d.ts +177 -0
- package/lib/types/src/host/integration/fs-provider.d.ts +226 -0
- package/lib/types/src/host/integration/lsp/lsp-framing.d.ts +38 -0
- package/lib/types/src/host/integration/lsp/lsp-registry.d.ts +67 -0
- package/lib/types/src/host/integration/lsp/lsp-session.d.ts +130 -0
- package/lib/types/src/host/integration/management-tools.d.ts +64 -0
- package/lib/types/src/host/integration/recycle-bin-service.d.ts +247 -0
- package/lib/types/src/host/integration/remote/connection-test.d.ts +73 -0
- package/lib/types/src/host/integration/remote/remote-face.d.ts +127 -0
- package/lib/types/src/host/integration/remote/remote-tool-backend.d.ts +108 -0
- package/lib/types/src/host/integration/remote-face.d.ts +127 -0
- package/lib/types/src/host/integration/remote-file-tools.d.ts +241 -0
- package/lib/types/src/host/integration/remote-home.d.ts +69 -0
- package/lib/types/src/host/integration/remote-index.d.ts +165 -0
- package/lib/types/src/host/integration/remote-job-tools.d.ts +295 -0
- package/lib/types/src/host/integration/remote-tool-backend.d.ts +97 -0
- package/lib/types/src/host/integration/remote-tools.d.ts +206 -0
- package/lib/types/src/host/integration/root-registry.d.ts +115 -0
- package/lib/types/src/host/integration/roots/anchor-directory.d.ts +56 -0
- package/lib/types/src/host/integration/roots/bin-root-resolver.d.ts +81 -0
- package/lib/types/src/host/integration/roots/remote-home.d.ts +69 -0
- package/lib/types/src/host/integration/roots/root-registry.d.ts +144 -0
- package/lib/types/src/host/integration/roots/roots-wiring.d.ts +219 -0
- package/lib/types/src/host/integration/roots/session-root-index.d.ts +52 -0
- package/lib/types/src/host/integration/roots-api.d.ts +407 -0
- package/lib/types/src/host/integration/roots-wiring.d.ts +211 -0
- package/lib/types/src/host/integration/session/session-api.d.ts +88 -0
- package/lib/types/src/host/integration/session/session-bin-lock.d.ts +80 -0
- package/lib/types/src/host/integration/session/session-header.d.ts +151 -0
- package/lib/types/src/host/integration/session/session-labels.d.ts +56 -0
- package/lib/types/src/host/integration/session/session-route-wiring.d.ts +50 -0
- package/lib/types/src/host/integration/session-admin-service.d.ts +236 -0
- package/lib/types/src/host/integration/session-api.d.ts +81 -0
- package/lib/types/src/host/integration/session-bin-lock.d.ts +80 -0
- package/lib/types/src/host/integration/session-header.d.ts +118 -0
- package/lib/types/src/host/integration/session-labels.d.ts +56 -0
- package/lib/types/src/host/integration/session-route-wiring.d.ts +50 -0
- package/lib/types/src/host/integration/session-scope.d.ts +113 -0
- package/lib/types/src/host/integration/session-tools.d.ts +44 -0
- package/lib/types/src/host/integration/strict-arguments.d.ts +79 -0
- package/lib/types/src/host/integration/takeover/takeover-api.d.ts +62 -0
- package/lib/types/src/host/integration/takeover/takeover-route-wiring.d.ts +60 -0
- package/lib/types/src/host/integration/takeover/takeover-service.d.ts +167 -0
- package/lib/types/src/host/integration/terminal-manifest.d.ts +94 -0
- package/lib/types/src/host/integration/tools/management-tools.d.ts +245 -0
- package/lib/types/src/host/integration/tools/remote-job-tools.d.ts +316 -0
- package/lib/types/src/host/integration/tools/remote-lsp-tools.d.ts +43 -0
- package/lib/types/src/host/integration/tools/remote-tools.d.ts +236 -0
- package/lib/types/src/host/integration/tools/session-target.d.ts +52 -0
- package/lib/types/src/host/integration/tools/session-tools.d.ts +46 -0
- package/lib/types/src/host/integration/tools/strict-arguments.d.ts +79 -0
- package/lib/types/src/host/integration/tools/terminal-manifest.d.ts +94 -0
- package/lib/types/src/host/integration/transfer/remote-copy.d.ts +66 -0
- package/lib/types/src/host/integration/transfer/transfer-adapters.d.ts +48 -0
- package/lib/types/src/host/integration/transfer/transfer-service.d.ts +212 -0
- package/lib/types/src/host/integration/transfer/transfer-tracker.d.ts +106 -0
- package/lib/types/src/host/integration/transfer-adapters.d.ts +44 -0
- package/lib/types/src/host/integration/transfer-service.d.ts +164 -0
- package/lib/types/src/host/integration/transfer-tracker.d.ts +106 -0
- package/lib/types/src/host/integration/user-roots.d.ts +461 -0
- package/lib/types/src/index.d.ts +66 -0
- package/lib/types/src/local-bridge-refs.d.ts +26 -0
- package/lib/types/src/local-bridge.d.ts +36 -0
- package/lib/types/src/shared/format.d.ts +13 -0
- package/lib/types/src/wiring/connections.d.ts +189 -0
- package/lib/types/src/wiring/fs.d.ts +13 -0
- package/lib/types/src/wiring/helpers.d.ts +144 -0
- package/lib/types/src/wiring/install-memo.d.ts +32 -0
- package/lib/types/src/wiring/legacy-dirs.d.ts +62 -0
- package/lib/types/src/wiring/package-paths.d.ts +35 -0
- package/lib/types/src/wiring/roots.d.ts +21 -0
- package/lib/types/src/wiring/state-dir.d.ts +29 -0
- package/lib/types/src/wiring/tools.d.ts +35 -0
- package/package.json +120 -4
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `alias` transport: the system OpenSSH client in ControlMaster mode.
|
|
3
|
+
*
|
|
4
|
+
* Why the system client: it inherits everything the user already configured — `~/.ssh/config`
|
|
5
|
+
* aliases, identity files, `ProxyJump`, `known_hosts`, ssh-agent — which is exactly the
|
|
6
|
+
* "import type { MultiplexingCache } from '../transport.ts';
|
|
7
|
+
|
|
8
|
+
import my ssh config and it just works" requirement. Password authentication is not offered
|
|
9
|
+
* here (a non-interactive `ssh` must not block on a prompt); the `ssh2` transport covers that.
|
|
10
|
+
*
|
|
11
|
+
* Remote file bytes travel as base64 over the multiplexed connection, so the plugin needs
|
|
12
|
+
* nothing installed on the remote host beyond POSIX `sh`, `base64` and (for version tokens)
|
|
13
|
+
* `stat` or `wc`.
|
|
14
|
+
*
|
|
15
|
+
* @module dsh-over-ssh/infra/transport/alias-transport
|
|
16
|
+
*/
|
|
17
|
+
import { type RemoteCapabilities } from '../../../domain/capability.ts';
|
|
18
|
+
import type { HostKeyPolicy } from '../../../domain/roots/connection.ts';
|
|
19
|
+
import { type ExecRequest, type ExecResult, type ReadFileRangeRequest, type ReadFileRequest, type RemoteFileChunk, type RemoteWriteOutcome, type RemoveRequest, type RenameRequest, type Transport, type TransportState, type WriteFileRangeRequest, type WriteFileRequest } from '../transport.ts';
|
|
20
|
+
import type { MultiplexingCache } from '../transport.ts';
|
|
21
|
+
export type { MultiplexingCache } from '../transport.ts';
|
|
22
|
+
/** One spawned process result as reported by the injected spawner. */
|
|
23
|
+
export interface SpawnResult {
|
|
24
|
+
readonly code: number;
|
|
25
|
+
readonly signal: string | null;
|
|
26
|
+
readonly stdout: string;
|
|
27
|
+
readonly stderr: string;
|
|
28
|
+
/** Whether the spawner cut stdout at the requested cap. */
|
|
29
|
+
readonly truncated?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the spawner dropped stderr bytes.
|
|
32
|
+
*
|
|
33
|
+
* Optional because a spawner is free not to track it; absent means "this spawner cannot say", and the
|
|
34
|
+
* transport then reports `false` rather than guessing. `createNodeSpawner` keeps only the first 64 stderr
|
|
35
|
+
* chunks, so it **does** drop bytes and must set this.
|
|
36
|
+
*/
|
|
37
|
+
readonly stderrTruncated?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the spawner's **own deadline** ended the process.
|
|
40
|
+
*
|
|
41
|
+
* Optional because a spawner that has no deadline cannot report it; absent means "this spawner cannot
|
|
42
|
+
* say", and the transport then reports `false` rather than blaming a timeout it never observed.
|
|
43
|
+
* `createNodeSpawner` kills the child on `timeoutMs` and **does** know, so it sets this.
|
|
44
|
+
*/
|
|
45
|
+
readonly timedOut?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Spawn options honoured by the injected spawner. */
|
|
48
|
+
export interface SpawnOptions {
|
|
49
|
+
readonly timeoutMs?: number;
|
|
50
|
+
readonly signal?: AbortSignal;
|
|
51
|
+
readonly stdin?: string;
|
|
52
|
+
readonly maxBytes?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Environment entries merged over the parent's environment for this child only.
|
|
55
|
+
*
|
|
56
|
+
* Exists for the `SSH_ASKPASS` wiring (`askpass.ts`): a password must reach the `ssh` child without being
|
|
57
|
+
* written to a file or interpolated into a command line. Absent means "inherit unchanged", which is what
|
|
58
|
+
* every other caller wants.
|
|
59
|
+
*/
|
|
60
|
+
readonly env?: Record<string, string>;
|
|
61
|
+
}
|
|
62
|
+
/** Injected process spawner (real: `node:child_process`; tests: a scripted fake). */
|
|
63
|
+
export type SpawnFn = (argv: readonly string[], options: SpawnOptions) => Promise<SpawnResult>;
|
|
64
|
+
/** How connection reuse is behaving for one transport. */
|
|
65
|
+
export type MultiplexingMode = 'unknown' | 'master' | 'unsupported' | 'off';
|
|
66
|
+
/**
|
|
67
|
+
* Remembers hosts whose `ssh` client cannot multiplex.
|
|
68
|
+
*
|
|
69
|
+
* The measurement that motivates this: the OpenSSH client shipped with Windows fails
|
|
70
|
+
* ControlMaster with `getsockname failed: Not a socket`, so retrying the master on every connect
|
|
71
|
+
* would cost a failed process per command sequence. See `doc/03-decisions/0006-…`.
|
|
72
|
+
*/
|
|
73
|
+
/** Create an in-memory multiplexing cache (one per process by default). */
|
|
74
|
+
export declare function createMultiplexingCache(): MultiplexingCache;
|
|
75
|
+
/** Process-wide cache shared by every alias transport. */
|
|
76
|
+
export declare const sharedMultiplexingCache: MultiplexingCache;
|
|
77
|
+
/**
|
|
78
|
+
* Whether a failed `ssh` run failed *because multiplexing is unavailable*, as opposed to a real
|
|
79
|
+
* connection problem.
|
|
80
|
+
*
|
|
81
|
+
* Deliberately narrow: a vanished control socket also mentions "control socket", but that is a
|
|
82
|
+
* connection loss (retryable), not "this client cannot multiplex" (permanent for this client).
|
|
83
|
+
*
|
|
84
|
+
* @param stderr - the failed client's stderr.
|
|
85
|
+
* @returns whether the failure indicates missing multiplexing support.
|
|
86
|
+
*/
|
|
87
|
+
export declare function isMultiplexingFailure(stderr: string): boolean;
|
|
88
|
+
/** Construction options for the alias transport. */
|
|
89
|
+
export interface AliasTransportOptions {
|
|
90
|
+
/** Connection id (also the pool key). */
|
|
91
|
+
readonly connectionId: string;
|
|
92
|
+
/** OpenSSH alias that carries user/port/identity/jump configuration. */
|
|
93
|
+
readonly alias: string;
|
|
94
|
+
/** Directory holding this plugin's ControlMaster sockets. */
|
|
95
|
+
readonly controlDir: string;
|
|
96
|
+
/** `ssh` executable; defaults to `ssh` on PATH. */
|
|
97
|
+
readonly sshBinary?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Identity file to pass as `-i`.
|
|
100
|
+
*
|
|
101
|
+
* The alias transport inherits `~/.ssh/config`, but when the connection **itself** names a key
|
|
102
|
+
* (`auth.kind === 'key'`) that key must win: silently ignoring it means the user's explicit choice only
|
|
103
|
+
* works if their config happens to agree (found by the agent-path e2e).
|
|
104
|
+
*/
|
|
105
|
+
readonly identityFile?: string;
|
|
106
|
+
/** Known-hosts file to pass as `-o UserKnownHostsFile`; omitted means ssh's own default. */
|
|
107
|
+
readonly knownHostsFile?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Remote user to pass as `-l`.
|
|
110
|
+
*
|
|
111
|
+
* Same reasoning as {@link identityFile}: when the connection names a user, that user must win. Without
|
|
112
|
+
* this, `ssh <bare-host>` silently used the **local** username (found by the agent-path e2e: the ladder
|
|
113
|
+
* failed with `yerier@host: Permission denied` even though the profile said `root`).
|
|
114
|
+
*/
|
|
115
|
+
readonly user?: string;
|
|
116
|
+
readonly hostKeyPolicy?: HostKeyPolicy;
|
|
117
|
+
readonly connectTimeoutMs?: number;
|
|
118
|
+
readonly commandTimeoutMs?: number;
|
|
119
|
+
readonly keepAliveSeconds?: number;
|
|
120
|
+
/** When true (default) authentication never prompts. */
|
|
121
|
+
readonly batchMode?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Extra environment for every `ssh` child this transport spawns.
|
|
124
|
+
*
|
|
125
|
+
* The askpass wiring lives here (`askpass.ts`): with a password connection the transport must both stop
|
|
126
|
+
* forbidding prompts ({@link batchMode} false) and hand ssh the helper that answers them. Passing it at
|
|
127
|
+
* construction means master, command and shutdown invocations all authenticate the same way — the drift
|
|
128
|
+
* that a per-call override would reintroduce.
|
|
129
|
+
*/
|
|
130
|
+
readonly env?: Record<string, string>;
|
|
131
|
+
/** `auto` (default) probes multiplexing and degrades; `off` never opens a master. */
|
|
132
|
+
readonly multiplexing?: 'auto' | 'off';
|
|
133
|
+
/** Injected cache so tests stay isolated; defaults to the process-wide cache. */
|
|
134
|
+
readonly multiplexingCache?: MultiplexingCache;
|
|
135
|
+
/** Injected spawner; the transport never touches `node:child_process` itself. */
|
|
136
|
+
readonly spawn: SpawnFn;
|
|
137
|
+
/** Injectable clock for diagnostics. */
|
|
138
|
+
readonly now?: () => number;
|
|
139
|
+
}
|
|
140
|
+
interface ParsedReadHeaders {
|
|
141
|
+
readonly size: number;
|
|
142
|
+
readonly mtime: number;
|
|
143
|
+
readonly bodyStart: number;
|
|
144
|
+
}
|
|
145
|
+
/** System-ssh transport with ControlMaster session reuse. */
|
|
146
|
+
export declare class AliasTransport implements Transport {
|
|
147
|
+
#private;
|
|
148
|
+
readonly id: string;
|
|
149
|
+
constructor(options: AliasTransportOptions);
|
|
150
|
+
get state(): TransportState;
|
|
151
|
+
get capabilities(): RemoteCapabilities;
|
|
152
|
+
/** Whether commands share one master connection, and why not when they do not. */
|
|
153
|
+
get multiplexing(): MultiplexingMode;
|
|
154
|
+
/** Human-readable reason when {@link multiplexing} is `unsupported`. */
|
|
155
|
+
multiplexingReason(): string | undefined;
|
|
156
|
+
/** Path of this connection's ControlMaster socket. */
|
|
157
|
+
controlPath(): string;
|
|
158
|
+
/** The argv that establishes (and persists) the multiplexed master connection. */
|
|
159
|
+
buildMasterArgv(): readonly string[];
|
|
160
|
+
/**
|
|
161
|
+
* The argv for one command.
|
|
162
|
+
*
|
|
163
|
+
* `-S` is only attached when a master connection actually exists: on a client without
|
|
164
|
+
* multiplexing it would make every command fail with a socket error.
|
|
165
|
+
*/
|
|
166
|
+
buildCommandArgv(command: string): readonly string[];
|
|
167
|
+
/** Establish the connection; concurrent calls share one attempt. */
|
|
168
|
+
connect(signal?: AbortSignal): Promise<void>;
|
|
169
|
+
/** Close the master connection when one exists. Idempotent. */
|
|
170
|
+
dispose(): Promise<void>;
|
|
171
|
+
/** Run one remote command. */
|
|
172
|
+
exec(request: ExecRequest, signal?: AbortSignal): Promise<ExecResult>;
|
|
173
|
+
/** Read a remote file with a version token from the same round trip. */
|
|
174
|
+
readFile(request: ReadFileRequest, signal?: AbortSignal): Promise<RemoteFileChunk>;
|
|
175
|
+
/** Write a remote file, optionally guarded by the digest of the current content. */
|
|
176
|
+
writeFile(request: WriteFileRequest, signal?: AbortSignal): Promise<RemoteWriteOutcome>;
|
|
177
|
+
/**
|
|
178
|
+
* Read `[offset, offset+maxBytes)` in one round trip.
|
|
179
|
+
*
|
|
180
|
+
* The command comes from `fs-commands.ts`, the same module the agent transport uses, so a shell offset read
|
|
181
|
+
* cannot drift between the two.
|
|
182
|
+
*/
|
|
183
|
+
readFileRange(request: ReadFileRangeRequest, signal?: AbortSignal): Promise<RemoteFileChunk>;
|
|
184
|
+
/** Write at `offset`, leaving the earlier bytes untouched (`dd conv=notrunc`). */
|
|
185
|
+
writeFileRange(request: WriteFileRangeRequest, signal?: AbortSignal): Promise<RemoteWriteOutcome>;
|
|
186
|
+
/** Move a path; a cross-device move fails instead of silently copying. */
|
|
187
|
+
rename(request: RenameRequest, signal?: AbortSignal): Promise<void>;
|
|
188
|
+
/** Remove a file or (with `recursive`) a directory tree. */
|
|
189
|
+
remove(request: RemoveRequest, signal?: AbortSignal): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Probe the remote host once and remember the result.
|
|
192
|
+
*
|
|
193
|
+
* @param signal - cancellation.
|
|
194
|
+
* @param maxAgeMs - reuse a previous probe inside this window (default 5 minutes).
|
|
195
|
+
* @returns the discovered capabilities.
|
|
196
|
+
*/
|
|
197
|
+
probeCapabilities(signal?: AbortSignal, maxAgeMs?: number): Promise<RemoteCapabilities>;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse the header lines emitted by {@link AliasTransport.readFile}.
|
|
201
|
+
*
|
|
202
|
+
* @param stdout - raw stdout of the read script.
|
|
203
|
+
* @returns size, mtime and the base64 body, or `undefined` when the headers are missing.
|
|
204
|
+
*/
|
|
205
|
+
export declare function parseReadHeaders(stdout: string): ParsedReadHeaders | undefined;
|
|
206
|
+
//# sourceMappingURL=alias-transport.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The real filesystem behind {@link AskpassIo}.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately tiny and separate, for the same reason `node-spawn.ts` is: the askpass logic is pure and
|
|
5
|
+
* testable, and this is the only module that touches a disk. Nothing here ever writes a secret — the
|
|
6
|
+
* helper it materialises reads the secret from the environment at run time.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-over-ssh/infra/transport/askpass-fs
|
|
9
|
+
*/
|
|
10
|
+
import type { AskpassIo } from './askpass.ts';
|
|
11
|
+
/**
|
|
12
|
+
* Build the production {@link AskpassIo}.
|
|
13
|
+
*
|
|
14
|
+
* The helper lives in a fresh private directory under the OS temp root, named with the plugin's prefix so a
|
|
15
|
+
* leftover is recognisable. Files are created `0o600`/`0o700` where the platform supports modes.
|
|
16
|
+
*
|
|
17
|
+
* @returns a filesystem adapter for {@link createAskpass}.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createAskpassFs(): AskpassIo;
|
|
20
|
+
//# sourceMappingURL=askpass-fs.d.ts.map
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-interactive **password** authentication for the system `ssh` client, via `SSH_ASKPASS`.
|
|
3
|
+
*
|
|
4
|
+
* Why this module exists: the Tier 2 agent is launched by spawning `ssh` (`ssh <alias> <agent> --stdio`),
|
|
5
|
+
* and the alias transport runs every command the same way. System `ssh` cannot read a password from a pipe,
|
|
6
|
+
* so a password-only connection used to be impossible on any transport that goes through `ssh` — which made
|
|
7
|
+
* "default to Tier 2" silently false for password connections (they were downgraded to `ssh2`). That was
|
|
8
|
+
* never a property of SSH: OpenSSH ≥ 8.4 supports `SSH_ASKPASS_REQUIRE=force`, which runs a helper program
|
|
9
|
+
* to obtain the secret **even with no tty**, exactly the situation a background plugin is in.
|
|
10
|
+
*
|
|
11
|
+
* Two rules make this safe:
|
|
12
|
+
*
|
|
13
|
+
* 1. **The secret never touches the disk.** The helper program carries no secret; it forwards the value of
|
|
14
|
+
* an environment variable (`DSH_OVER_SSH_ASKPASS_SECRET`) that the ssh child process inherits. A leftover
|
|
15
|
+
* helper file therefore leaks nothing: with the variable absent it prints an empty line and ssh fails
|
|
16
|
+
* the authentication instead of succeeding with a stale credential.
|
|
17
|
+
* 2. **The secret is never interpolated into a shell or command line.** It travels only as an environment
|
|
18
|
+
* value, so characters like `&`, `|`, `%`, `^` and quotes need no escaping (a `cmd`-based helper that
|
|
19
|
+
* echoed the secret would break on those, and its argv would be visible in the process list).
|
|
20
|
+
*
|
|
21
|
+
* Verified on the real host (Windows, OpenSSH_for_Windows_9.5p1): password auth succeeds through a spawned
|
|
22
|
+
* `ssh` whose stdio are pipes, and a **wrong** secret fails — so the helper is genuinely what authenticates.
|
|
23
|
+
*
|
|
24
|
+
* @module dsh-over-ssh/infra/transport/askpass
|
|
25
|
+
*/
|
|
26
|
+
/** The interpreter that runs the helper script. */
|
|
27
|
+
export interface AskpassInterpreter {
|
|
28
|
+
/** Absolute path of the executable (`node`/Electron). */
|
|
29
|
+
readonly execPath: string;
|
|
30
|
+
/** `'win32'` or a POSIX platform id; decides which shim shape is written. */
|
|
31
|
+
readonly platform: string;
|
|
32
|
+
}
|
|
33
|
+
/** The two files a helper is made of, and the exact text written to each. */
|
|
34
|
+
export interface AskpassFiles {
|
|
35
|
+
/** The program `SSH_ASKPASS` points at. */
|
|
36
|
+
readonly helperPath: string;
|
|
37
|
+
/** The script the helper delegates to. */
|
|
38
|
+
readonly scriptPath: string;
|
|
39
|
+
/** Contents of {@link scriptPath}; carries no secret. */
|
|
40
|
+
readonly script: string;
|
|
41
|
+
/** Contents of {@link helperPath}; carries no secret. */
|
|
42
|
+
readonly helper: string;
|
|
43
|
+
/** Mode to create the files with (POSIX needs the helper executable). */
|
|
44
|
+
readonly mode: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The helper script: print the secret from the environment, then a newline.
|
|
48
|
+
*
|
|
49
|
+
* A trailing newline is required — an ssh askpass program whose output lacks one is rejected
|
|
50
|
+
* (measured: `<nul set /p =` without a newline failed while `echo` succeeded).
|
|
51
|
+
*/
|
|
52
|
+
export declare function askpassScript(): string;
|
|
53
|
+
/**
|
|
54
|
+
* The program `SSH_ASKPASS` names.
|
|
55
|
+
*
|
|
56
|
+
* Windows: a `cmd` shim, because ssh executes the path directly and a `.mjs` is not executable there.
|
|
57
|
+
* POSIX: a `sh` script. Both only *launch* the interpreter with the script path, so the secret is never
|
|
58
|
+
* quoted into a command line.
|
|
59
|
+
*
|
|
60
|
+
* @param interpreter - interpreter and platform.
|
|
61
|
+
* @param scriptPath - absolute path of {@link askpassScript}'s file.
|
|
62
|
+
* @returns the shim text.
|
|
63
|
+
*/
|
|
64
|
+
export declare function askpassHelper(interpreter: AskpassInterpreter, scriptPath: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Build the files for one helper directory.
|
|
67
|
+
*
|
|
68
|
+
* @param dir - directory to place the helper in.
|
|
69
|
+
* @param interpreter - interpreter and platform.
|
|
70
|
+
* @returns the file plan (paths plus contents).
|
|
71
|
+
*/
|
|
72
|
+
export declare function planAskpassFiles(dir: string, interpreter: AskpassInterpreter): AskpassFiles;
|
|
73
|
+
/**
|
|
74
|
+
* The environment that makes the system `ssh` ask {@link AskpassFiles.helperPath} for the password.
|
|
75
|
+
*
|
|
76
|
+
* `ELECTRON_RUN_AS_NODE=1` is set unconditionally: this plugin normally runs inside the Electron desktop
|
|
77
|
+
* app, where `process.execPath` is the Electron binary and would otherwise open a GUI instead of running
|
|
78
|
+
* the script. Real `node` ignores the variable, so one code path covers both hosts.
|
|
79
|
+
*
|
|
80
|
+
* `DISPLAY` is set because pre-8.4 OpenSSH only consults `SSH_ASKPASS` when it is non-empty, and
|
|
81
|
+
* `SSH_ASKPASS_REQUIRE=force` because ≥ 8.4 additionally requires it when a tty might exist. Setting both
|
|
82
|
+
* makes the helper work on either generation.
|
|
83
|
+
*
|
|
84
|
+
* @param files - the helper plan.
|
|
85
|
+
* @param secret - the password; only ever passed here, never written to a file.
|
|
86
|
+
* @returns environment entries to merge into the `ssh` child's environment.
|
|
87
|
+
*/
|
|
88
|
+
export declare function askpassEnvironment(files: AskpassFiles, secret: string): Record<string, string>;
|
|
89
|
+
/** Filesystem surface this module needs; injected so tests never touch a real disk. */
|
|
90
|
+
export interface AskpassIo {
|
|
91
|
+
/** Create `dir` (and parents). */
|
|
92
|
+
mkdir(dir: string): Promise<void>;
|
|
93
|
+
/** Write `content` to `path`, optionally with a POSIX mode. */
|
|
94
|
+
writeFile(path: string, content: string, mode: number): Promise<void>;
|
|
95
|
+
/** Remove `dir` recursively; never throws when it is already gone. */
|
|
96
|
+
remove(dir: string): Promise<void>;
|
|
97
|
+
/** Create a private directory to hold one helper. */
|
|
98
|
+
makeTempDir(): Promise<string>;
|
|
99
|
+
}
|
|
100
|
+
/** A live helper: the environment to hand `ssh`, plus a way to take it away again. */
|
|
101
|
+
export interface AskpassHandle {
|
|
102
|
+
/** Environment entries for the `ssh` child process. */
|
|
103
|
+
readonly env: Record<string, string>;
|
|
104
|
+
/** Delete the helper directory. Safe to call more than once. */
|
|
105
|
+
dispose(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/** Options for {@link createAskpass}. */
|
|
108
|
+
export interface AskpassOptions {
|
|
109
|
+
/** The password. Held in memory only. */
|
|
110
|
+
readonly secret: string;
|
|
111
|
+
/** Interpreter facts; defaults to this process. */
|
|
112
|
+
readonly interpreter?: AskpassInterpreter;
|
|
113
|
+
/** Injected filesystem. */
|
|
114
|
+
readonly io: AskpassIo;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a password helper and the environment that uses it.
|
|
118
|
+
*
|
|
119
|
+
* @param options - secret, interpreter and injected filesystem.
|
|
120
|
+
* @returns the handle; call {@link AskpassHandle.dispose} when the connection goes away.
|
|
121
|
+
*/
|
|
122
|
+
export declare function createAskpass(options: AskpassOptions): Promise<AskpassHandle>;
|
|
123
|
+
/**
|
|
124
|
+
* Whether a connection's password can be handed to the system `ssh` at all.
|
|
125
|
+
*
|
|
126
|
+
* Only `authKind: 'password'` needs the helper: key and agent connections never prompt, and forcing
|
|
127
|
+
* `BatchMode=no` for them would let a misconfigured host block on an interactive prompt forever.
|
|
128
|
+
*
|
|
129
|
+
* @param authKind - the connection's authentication mode.
|
|
130
|
+
* @returns true when the askpass helper must be wired in.
|
|
131
|
+
*/
|
|
132
|
+
export declare function needsAskpass(authKind: 'agent' | 'key' | 'password'): boolean;
|
|
133
|
+
//# sourceMappingURL=askpass.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POSIX shell quoting for remote command construction.
|
|
3
|
+
*
|
|
4
|
+
* Remote commands are the plugin's one injection surface: `ssh <alias> <command>` runs the
|
|
5
|
+
* command through the remote login shell, so every interpolated value must be quoted. The
|
|
6
|
+
* `argv`-first design keeps quoting to the places that genuinely need a shell.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-over-ssh/infra/transport/shell-quote
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Quote one value for a POSIX shell so it cannot be interpreted.
|
|
12
|
+
*
|
|
13
|
+
* Thin alias over {@link quote} in the domain: the implementation lives there because `domain` must not
|
|
14
|
+
* depend on `infra` (red line #2), and the terminal wrapper + tool-request builders need the same function.
|
|
15
|
+
* Keeping this name means the 41 ssh-transport call sites do not have to change.
|
|
16
|
+
*
|
|
17
|
+
* @param value - raw value.
|
|
18
|
+
* @returns a shell-safe literal.
|
|
19
|
+
* @throws SshDevError when the value contains a NUL byte.
|
|
20
|
+
*/
|
|
21
|
+
export declare function shellQuote(value: string): string;
|
|
22
|
+
/** Quote several values and join them with spaces. */
|
|
23
|
+
export declare function shellQuoteAll(values: readonly string[]): string;
|
|
24
|
+
/** How a remote command is assembled. */
|
|
25
|
+
export interface RemoteCommandOptions {
|
|
26
|
+
/** Directory to `cd` into before running; omitted leaves the remote default. */
|
|
27
|
+
readonly cwd?: string;
|
|
28
|
+
/** Environment assignments applied to the command only. */
|
|
29
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build a remote command string from an argv vector.
|
|
33
|
+
*
|
|
34
|
+
* @param argv - executable followed by arguments; never shell-interpreted as a whole.
|
|
35
|
+
* @param options - optional `cwd` and environment.
|
|
36
|
+
* @returns a command string safe to pass as the single `ssh` command argument.
|
|
37
|
+
* @throws SshDevError when `argv` is empty or a value carries a NUL.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildRemoteCommand(argv: readonly string[], options?: RemoteCommandOptions): string;
|
|
40
|
+
/**
|
|
41
|
+
* Prefix lines that make a **script** honour `cwd` and `env`.
|
|
42
|
+
*
|
|
43
|
+
* The argv path builds these into one command; the script path must apply them too, because dropping them
|
|
44
|
+
* silently is the worst outcome — a real-host run showed `remote_exec { cwd: 'src' }` running in `$HOME` and
|
|
45
|
+
* reporting success. Shared by every shell transport so the two paths cannot drift apart again.
|
|
46
|
+
*
|
|
47
|
+
* @param request - requested `cwd` and environment.
|
|
48
|
+
* @returns prefix lines, `cd` first; empty when neither was requested.
|
|
49
|
+
* @throws SshDevError when an environment name is not a shell identifier.
|
|
50
|
+
*/
|
|
51
|
+
export declare function scriptPrefixes(request: RemoteCommandOptions): readonly string[];
|
|
52
|
+
/**
|
|
53
|
+
* Build a remote command from a raw script body.
|
|
54
|
+
*
|
|
55
|
+
* The caller owns the script text; values interpolated into it must already be quoted with
|
|
56
|
+
* {@link shellQuote}.
|
|
57
|
+
*
|
|
58
|
+
* @param script - POSIX shell script body.
|
|
59
|
+
* @returns the command string.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildRemoteScript(script: string): string;
|
|
62
|
+
//# sourceMappingURL=shell-quote.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that decides which `ssh` arguments a connection's credentials turn into.
|
|
3
|
+
*
|
|
4
|
+
* Two call sites need exactly the same answer — the alias transport (which builds master and per-command
|
|
5
|
+
* argv) and the Tier 2 agent launcher (which spawns `ssh <alias> <agent> --stdio`) — and the agent-path e2e
|
|
6
|
+
* caught both of them drifting: the transport ignored `keyPath`, then the launcher ignored `user`, so the
|
|
7
|
+
* ladder authenticated and the agent session did not. Duplicating this list is what allowed that.
|
|
8
|
+
*
|
|
9
|
+
* Honesty rule: a value is only emitted when the connection actually set it. Emitting `-l`/`-i`
|
|
10
|
+
* unconditionally would override the user's own `~/.ssh/config`, which is the alias transport's whole point.
|
|
11
|
+
*
|
|
12
|
+
* @module dsh-over-ssh/infra/transport/ssh-argv
|
|
13
|
+
*/
|
|
14
|
+
import type { HostKeyPolicy } from '../../../domain/roots/connection.ts';
|
|
15
|
+
/** Credential-ish options shared by every `ssh` invocation this plugin makes. */
|
|
16
|
+
export interface SshArgvOptions {
|
|
17
|
+
/** Destination: an `~/.ssh/config` alias or a bare `user@host`-less host. */
|
|
18
|
+
readonly alias: string;
|
|
19
|
+
/** Remote user; omitted or empty means "let ssh decide". */
|
|
20
|
+
readonly user?: string;
|
|
21
|
+
/** `-i` identity file. */
|
|
22
|
+
readonly identityFile?: string;
|
|
23
|
+
/** `-o UserKnownHostsFile=…`. */
|
|
24
|
+
readonly knownHostsFile?: string;
|
|
25
|
+
readonly hostKeyPolicy?: HostKeyPolicy;
|
|
26
|
+
readonly connectTimeoutMs?: number;
|
|
27
|
+
/** `-o BatchMode=yes` (never prompt). Defaults to true: this plugin never has a human at the tty. */
|
|
28
|
+
readonly batchMode?: boolean;
|
|
29
|
+
/** Extra `-o` options appended verbatim, in order. */
|
|
30
|
+
readonly extraOptions?: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
/** `-i`, `-o UserKnownHostsFile`, `-l` — only what the connection configured. */
|
|
33
|
+
export declare function credentialArgv(options: SshArgvOptions): readonly string[];
|
|
34
|
+
/** Common `-o` options (policy, timeout, batch mode) plus {@link credentialArgv}. */
|
|
35
|
+
export declare function commonSshOptions(options: SshArgvOptions): readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* A complete `ssh` prefix ending at the destination: `ssh -T <options…> <alias>`.
|
|
38
|
+
*
|
|
39
|
+
* The Tier 2 launcher appends the remote command to this; the alias transport appends its own control
|
|
40
|
+
* sockets and the command.
|
|
41
|
+
*/
|
|
42
|
+
export declare function sshPrefix(sshBinary: string, options: SshArgvOptions): readonly string[];
|
|
43
|
+
//# sourceMappingURL=ssh-argv.d.ts.map
|