dsh-over-ssh 0.1.0 → 0.1.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/README.md +10 -10
- package/agents/agent-manifest.json +1 -1
- package/lib/client.js +363 -314
- package/lib/file-references.js +80 -35
- package/lib/fs.js +158 -75
- package/lib/index.js +4103 -3397
- package/lib/terminal-wrapper.js +9 -4
- package/lib/types/src/config.d.ts +80 -9
- package/lib/types/src/file-references.d.ts +0 -1
- package/lib/types/src/host/app/backend.d.ts +9 -1
- package/lib/types/src/host/app/recycle-bin/recycle-bin-contract.d.ts +0 -1
- package/lib/types/src/host/app/recycle-bin/recycle-bin-service.d.ts +0 -1
- package/lib/types/src/host/app/session-admin/session-admin-contract.d.ts +12 -1
- package/lib/types/src/host/app/session-admin/session-admin-service.d.ts +0 -1
- package/lib/types/src/host/app/transport/transport-selector.d.ts +0 -1
- package/lib/types/src/host/app/transport/transport-service.d.ts +0 -1
- package/lib/types/src/host/domain/capability.d.ts +0 -1
- package/lib/types/src/host/domain/errors.d.ts +0 -1
- package/lib/types/src/host/domain/roots/connection.d.ts +0 -1
- package/lib/types/src/host/domain/roots/root.d.ts +24 -9
- package/lib/types/src/host/domain/roots/session-roots.d.ts +0 -1
- package/lib/types/src/host/domain/roots/ssh-config.d.ts +0 -1
- package/lib/types/src/host/domain/session/session-admin.d.ts +0 -1
- package/lib/types/src/host/domain/transfer/recycle-bin.d.ts +0 -1
- package/lib/types/src/host/domain/transfer/transfer.d.ts +0 -1
- package/lib/types/src/host/infra/transport/agent/agent-installer.d.ts +0 -1
- package/lib/types/src/host/infra/transport/ssh/ssh2-transport.d.ts +0 -1
- package/lib/types/src/host/infra/transport/transport-base.d.ts +0 -1
- package/lib/types/src/host/infra/transport/transport.d.ts +16 -2
- package/lib/types/src/host/integration/agent/agent-preflight.d.ts +0 -1
- package/lib/types/src/host/integration/fs/file-reference-provider.d.ts +0 -1
- package/lib/types/src/host/integration/fs/fs-provider.d.ts +0 -2
- package/lib/types/src/host/integration/transfer/transfer-service.d.ts +0 -1
- package/lib/types/src/index.d.ts +23 -1
- package/lib/types/src/local-bridge-refs.d.ts +0 -1
- package/lib/types/src/local-bridge.d.ts +0 -1
- package/lib/types/src/shared/root-keys.d.ts +120 -0
- package/lib/types/src/wiring/helpers.d.ts +0 -1
- package/package.json +5 -3
- package/lib/types/src/client/controls.d.ts +0 -131
- package/lib/types/src/client/core/card-focus-trap.d.ts +0 -45
- package/lib/types/src/client/core/controls.d.ts +0 -164
- package/lib/types/src/client/core/latest.d.ts +0 -48
- package/lib/types/src/client/core/locale.d.ts +0 -38
- package/lib/types/src/client/core/message.d.ts +0 -37
- package/lib/types/src/client/core/panel-model.d.ts +0 -134
- package/lib/types/src/client/core/portal.d.ts +0 -266
- package/lib/types/src/client/core/remote.d.ts +0 -84
- package/lib/types/src/client/core/styles.d.ts +0 -458
- package/lib/types/src/client/file-tree-io.d.ts +0 -19
- package/lib/types/src/client/file-tree.d.ts +0 -271
- package/lib/types/src/client/flows/directory-browser.d.ts +0 -587
- package/lib/types/src/client/flows/session-directory.d.ts +0 -415
- package/lib/types/src/client/flows/workspace-directory-flow.d.ts +0 -480
- package/lib/types/src/client/locale.d.ts +0 -31
- package/lib/types/src/client/panel-model.d.ts +0 -37
- package/lib/types/src/client/panel.d.ts +0 -77
- package/lib/types/src/client/roots/connection-test.d.ts +0 -69
- package/lib/types/src/client/roots/roots-panel-state.d.ts +0 -307
- package/lib/types/src/client/roots/roots-panel-view.d.ts +0 -280
- package/lib/types/src/client/roots/roots-panel.d.ts +0 -364
- package/lib/types/src/client/roots/transfer-panel-view.d.ts +0 -35
- package/lib/types/src/client/roots/transfer-panel.d.ts +0 -241
- package/lib/types/src/client/roots/transfer-progress.d.ts +0 -67
- package/lib/types/src/client/roots-panel-view.d.ts +0 -236
- package/lib/types/src/client/roots-panel.d.ts +0 -347
- package/lib/types/src/client/session/session-panel-view.d.ts +0 -336
- package/lib/types/src/client/session/session-panel.d.ts +0 -322
- package/lib/types/src/client/session/session-remote-mark.d.ts +0 -110
- package/lib/types/src/client/session/session-row-actions.d.ts +0 -398
- package/lib/types/src/client/session-panel.d.ts +0 -152
- package/lib/types/src/client/styles.d.ts +0 -252
- package/lib/types/src/client/workspace-directory-flow.d.ts +0 -342
- package/lib/types/src/fs.d.ts +0 -46
- package/lib/types/src/host/app/recycle-bin/recycle-bin-move.d.ts +0 -18
- package/lib/types/src/host/app/recycle-bin/recycle-bin-world.d.ts +0 -38
- package/lib/types/src/host/app/recycle-bin-contract.d.ts +0 -215
- package/lib/types/src/host/app/recycle-bin-move.d.ts +0 -18
- package/lib/types/src/host/app/recycle-bin-service.d.ts +0 -45
- package/lib/types/src/host/app/recycle-bin-world.d.ts +0 -35
- package/lib/types/src/host/app/roots/roots-api-connections.d.ts +0 -49
- package/lib/types/src/host/app/roots/roots-api-contract.d.ts +0 -369
- package/lib/types/src/host/app/roots/roots-api-directories.d.ts +0 -13
- package/lib/types/src/host/app/roots/roots-api-http.d.ts +0 -77
- package/lib/types/src/host/app/roots/roots-api-long-poll.d.ts +0 -130
- package/lib/types/src/host/app/roots/roots-api-projections.d.ts +0 -102
- package/lib/types/src/host/app/roots/roots-api-roots.d.ts +0 -13
- package/lib/types/src/host/app/roots/roots-api-state.d.ts +0 -22
- package/lib/types/src/host/app/roots/roots-api-transfers.d.ts +0 -26
- package/lib/types/src/host/app/roots/roots-api.d.ts +0 -55
- package/lib/types/src/host/app/roots/user-roots.d.ts +0 -552
- package/lib/types/src/host/app/roots-api-connections.d.ts +0 -49
- package/lib/types/src/host/app/roots-api-contract.d.ts +0 -339
- package/lib/types/src/host/app/roots-api-directories.d.ts +0 -13
- package/lib/types/src/host/app/roots-api-http.d.ts +0 -77
- package/lib/types/src/host/app/roots-api-projections.d.ts +0 -102
- package/lib/types/src/host/app/roots-api-roots.d.ts +0 -13
- package/lib/types/src/host/app/roots-api-state.d.ts +0 -22
- package/lib/types/src/host/app/roots-api-support.d.ts +0 -182
- package/lib/types/src/host/app/roots-api-transfers.d.ts +0 -13
- package/lib/types/src/host/app/roots-api.d.ts +0 -55
- package/lib/types/src/host/app/routed-fs.d.ts +0 -239
- package/lib/types/src/host/app/serialize.d.ts +0 -37
- package/lib/types/src/host/app/session-admin/session-admin-context.d.ts +0 -36
- package/lib/types/src/host/app/session-admin/session-admin-delete.d.ts +0 -34
- package/lib/types/src/host/app/session-admin-context.d.ts +0 -36
- package/lib/types/src/host/app/session-admin-contract.d.ts +0 -214
- package/lib/types/src/host/app/session-admin-delete.d.ts +0 -34
- package/lib/types/src/host/app/session-admin-service.d.ts +0 -38
- package/lib/types/src/host/app/takeover/takeover-plan.d.ts +0 -227
- package/lib/types/src/host/app/takeover/takeover-rows.d.ts +0 -55
- package/lib/types/src/host/app/transport-selector.d.ts +0 -98
- package/lib/types/src/host/app/transport-service.d.ts +0 -75
- package/lib/types/src/host/app/user-roots.d.ts +0 -461
- package/lib/types/src/host/domain/bin-location.d.ts +0 -79
- package/lib/types/src/host/domain/connection.d.ts +0 -95
- package/lib/types/src/host/domain/glob-pattern.d.ts +0 -62
- package/lib/types/src/host/domain/literal-text.d.ts +0 -63
- package/lib/types/src/host/domain/path-grammar.d.ts +0 -84
- package/lib/types/src/host/domain/recycle-bin.d.ts +0 -337
- package/lib/types/src/host/domain/root.d.ts +0 -74
- package/lib/types/src/host/domain/roots/bin-location.d.ts +0 -91
- package/lib/types/src/host/domain/roots/route-table.d.ts +0 -102
- package/lib/types/src/host/domain/route-table.d.ts +0 -80
- package/lib/types/src/host/domain/session/terminal-target.d.ts +0 -136
- package/lib/types/src/host/domain/session-admin.d.ts +0 -330
- package/lib/types/src/host/domain/shell.d.ts +0 -47
- package/lib/types/src/host/domain/ssh-config.d.ts +0 -73
- package/lib/types/src/host/domain/terminal-target.d.ts +0 -132
- package/lib/types/src/host/domain/tool-requests.d.ts +0 -369
- package/lib/types/src/host/domain/transfer.d.ts +0 -260
- package/lib/types/src/host/infra/backend/local-backend.d.ts +0 -84
- package/lib/types/src/host/infra/backend/local-version.d.ts +0 -43
- package/lib/types/src/host/infra/backend/platform-local-backend.d.ts +0 -89
- package/lib/types/src/host/infra/backend/remote-backend.d.ts +0 -239
- package/lib/types/src/host/infra/cache/lru.d.ts +0 -52
- package/lib/types/src/host/infra/cache/versioned.d.ts +0 -77
- package/lib/types/src/host/infra/temp-name.d.ts +0 -19
- package/lib/types/src/host/infra/transport/agent/agent-protocol-client.d.ts +0 -132
- package/lib/types/src/host/infra/transport/agent/agent-protocol-codec.d.ts +0 -140
- package/lib/types/src/host/infra/transport/agent/agent-protocol-errors.d.ts +0 -41
- package/lib/types/src/host/infra/transport/agent/agent-protocol-frames.d.ts +0 -197
- package/lib/types/src/host/infra/transport/agent/agent-protocol-types.d.ts +0 -564
- package/lib/types/src/host/infra/transport/agent/agent-transport.d.ts +0 -418
- package/lib/types/src/host/infra/transport/agent-installer.d.ts +0 -121
- package/lib/types/src/host/infra/transport/agent-protocol-client.d.ts +0 -123
- package/lib/types/src/host/infra/transport/agent-protocol-codec.d.ts +0 -131
- package/lib/types/src/host/infra/transport/agent-protocol-errors.d.ts +0 -41
- package/lib/types/src/host/infra/transport/agent-protocol-frames.d.ts +0 -197
- package/lib/types/src/host/infra/transport/agent-protocol-types.d.ts +0 -509
- package/lib/types/src/host/infra/transport/agent-transport.d.ts +0 -353
- package/lib/types/src/host/infra/transport/alias-transport.d.ts +0 -206
- package/lib/types/src/host/infra/transport/askpass-fs.d.ts +0 -20
- package/lib/types/src/host/infra/transport/askpass.d.ts +0 -133
- package/lib/types/src/host/infra/transport/command-pool.d.ts +0 -61
- package/lib/types/src/host/infra/transport/fs-commands.d.ts +0 -140
- package/lib/types/src/host/infra/transport/git-status-route.d.ts +0 -63
- package/lib/types/src/host/infra/transport/git-status.d.ts +0 -101
- package/lib/types/src/host/infra/transport/node-spawn.d.ts +0 -26
- package/lib/types/src/host/infra/transport/session-window.d.ts +0 -51
- package/lib/types/src/host/infra/transport/shell-quote.d.ts +0 -59
- package/lib/types/src/host/infra/transport/ssh/alias-transport.d.ts +0 -206
- package/lib/types/src/host/infra/transport/ssh/askpass-fs.d.ts +0 -20
- package/lib/types/src/host/infra/transport/ssh/askpass.d.ts +0 -133
- package/lib/types/src/host/infra/transport/ssh/shell-quote.d.ts +0 -62
- package/lib/types/src/host/infra/transport/ssh/ssh-argv.d.ts +0 -43
- package/lib/types/src/host/infra/transport/ssh-argv.d.ts +0 -43
- package/lib/types/src/host/infra/transport/ssh2-transport.d.ts +0 -302
- package/lib/types/src/host/integration/agent/agent-install-io.d.ts +0 -33
- package/lib/types/src/host/integration/agent/askpass-registry.d.ts +0 -66
- package/lib/types/src/host/integration/agent-install-io.d.ts +0 -33
- package/lib/types/src/host/integration/agent-preflight.d.ts +0 -56
- package/lib/types/src/host/integration/anchor-directory.d.ts +0 -56
- package/lib/types/src/host/integration/askpass-registry.d.ts +0 -59
- package/lib/types/src/host/integration/bin-root-resolver.d.ts +0 -81
- package/lib/types/src/host/integration/connection-test.d.ts +0 -73
- package/lib/types/src/host/integration/file-reference-provider.d.ts +0 -115
- package/lib/types/src/host/integration/fs/git-status-wiring.d.ts +0 -21
- package/lib/types/src/host/integration/fs/platform-errors.d.ts +0 -94
- package/lib/types/src/host/integration/fs/remote-file-tools.d.ts +0 -369
- package/lib/types/src/host/integration/fs/remote-index.d.ts +0 -177
- package/lib/types/src/host/integration/fs-provider.d.ts +0 -226
- package/lib/types/src/host/integration/lsp/lsp-framing.d.ts +0 -38
- package/lib/types/src/host/integration/lsp/lsp-registry.d.ts +0 -67
- package/lib/types/src/host/integration/lsp/lsp-session.d.ts +0 -130
- package/lib/types/src/host/integration/management-tools.d.ts +0 -64
- package/lib/types/src/host/integration/recycle-bin-service.d.ts +0 -247
- package/lib/types/src/host/integration/remote/connection-test.d.ts +0 -73
- package/lib/types/src/host/integration/remote/remote-face.d.ts +0 -127
- package/lib/types/src/host/integration/remote/remote-tool-backend.d.ts +0 -108
- package/lib/types/src/host/integration/remote-face.d.ts +0 -127
- package/lib/types/src/host/integration/remote-file-tools.d.ts +0 -241
- package/lib/types/src/host/integration/remote-home.d.ts +0 -69
- package/lib/types/src/host/integration/remote-index.d.ts +0 -165
- package/lib/types/src/host/integration/remote-job-tools.d.ts +0 -295
- package/lib/types/src/host/integration/remote-tool-backend.d.ts +0 -97
- package/lib/types/src/host/integration/remote-tools.d.ts +0 -206
- package/lib/types/src/host/integration/root-registry.d.ts +0 -115
- package/lib/types/src/host/integration/roots/anchor-directory.d.ts +0 -56
- package/lib/types/src/host/integration/roots/bin-root-resolver.d.ts +0 -81
- package/lib/types/src/host/integration/roots/remote-home.d.ts +0 -69
- package/lib/types/src/host/integration/roots/root-registry.d.ts +0 -144
- package/lib/types/src/host/integration/roots/roots-wiring.d.ts +0 -219
- package/lib/types/src/host/integration/roots/session-root-index.d.ts +0 -52
- package/lib/types/src/host/integration/roots-api.d.ts +0 -407
- package/lib/types/src/host/integration/roots-wiring.d.ts +0 -211
- package/lib/types/src/host/integration/session/session-api.d.ts +0 -88
- package/lib/types/src/host/integration/session/session-bin-lock.d.ts +0 -80
- package/lib/types/src/host/integration/session/session-header.d.ts +0 -151
- package/lib/types/src/host/integration/session/session-labels.d.ts +0 -56
- package/lib/types/src/host/integration/session/session-route-wiring.d.ts +0 -50
- package/lib/types/src/host/integration/session-admin-service.d.ts +0 -236
- package/lib/types/src/host/integration/session-api.d.ts +0 -81
- package/lib/types/src/host/integration/session-bin-lock.d.ts +0 -80
- package/lib/types/src/host/integration/session-header.d.ts +0 -118
- package/lib/types/src/host/integration/session-labels.d.ts +0 -56
- package/lib/types/src/host/integration/session-route-wiring.d.ts +0 -50
- package/lib/types/src/host/integration/session-scope.d.ts +0 -113
- package/lib/types/src/host/integration/session-tools.d.ts +0 -44
- package/lib/types/src/host/integration/strict-arguments.d.ts +0 -79
- package/lib/types/src/host/integration/takeover/takeover-api.d.ts +0 -62
- package/lib/types/src/host/integration/takeover/takeover-route-wiring.d.ts +0 -60
- package/lib/types/src/host/integration/takeover/takeover-service.d.ts +0 -167
- package/lib/types/src/host/integration/terminal-manifest.d.ts +0 -94
- package/lib/types/src/host/integration/tools/management-tools.d.ts +0 -245
- package/lib/types/src/host/integration/tools/remote-job-tools.d.ts +0 -316
- package/lib/types/src/host/integration/tools/remote-lsp-tools.d.ts +0 -43
- package/lib/types/src/host/integration/tools/remote-tools.d.ts +0 -236
- package/lib/types/src/host/integration/tools/session-target.d.ts +0 -52
- package/lib/types/src/host/integration/tools/session-tools.d.ts +0 -46
- package/lib/types/src/host/integration/tools/strict-arguments.d.ts +0 -79
- package/lib/types/src/host/integration/tools/terminal-manifest.d.ts +0 -94
- package/lib/types/src/host/integration/transfer/remote-copy.d.ts +0 -66
- package/lib/types/src/host/integration/transfer/transfer-adapters.d.ts +0 -48
- package/lib/types/src/host/integration/transfer/transfer-tracker.d.ts +0 -106
- package/lib/types/src/host/integration/transfer-adapters.d.ts +0 -44
- package/lib/types/src/host/integration/transfer-service.d.ts +0 -164
- package/lib/types/src/host/integration/transfer-tracker.d.ts +0 -106
- package/lib/types/src/host/integration/user-roots.d.ts +0 -461
- package/lib/types/src/wiring/connections.d.ts +0 -189
- package/lib/types/src/wiring/fs.d.ts +0 -13
- package/lib/types/src/wiring/install-memo.d.ts +0 -32
- package/lib/types/src/wiring/legacy-dirs.d.ts +0 -62
- package/lib/types/src/wiring/package-paths.d.ts +0 -35
- package/lib/types/src/wiring/roots.d.ts +0 -21
- package/lib/types/src/wiring/state-dir.d.ts +0 -29
- package/lib/types/src/wiring/tools.d.ts +0 -35
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 代理协议的**编解码层**:请求参数压缩与响应结果读取。
|
|
3
|
-
*
|
|
4
|
-
* 从 `agent-protocol-client.ts` 拆出(审计 0079)。全部是纯函数——无 I/O、无类、无状态,
|
|
5
|
-
* 因此可以脱离客户端单独测试。客户端只负责"发出去、等回来、配对",
|
|
6
|
-
* 把线上格式(ns→ms、缺省值、字符串枚举)留给这一层。
|
|
7
|
-
*
|
|
8
|
-
* @module dsh-remote-workspace/infra/transport/agent-protocol-codec
|
|
9
|
-
*/
|
|
10
|
-
import { type ExecRequest } from './transport.ts';
|
|
11
|
-
import type { AgentIndexEntry, AgentIndexScanResult, AgentProcStartRequest, AgentJobStatus, AgentJobOutput, AgentLspStartRequest, AgentLspStatus, AgentLspRead, AgentIndexScanRequest, AgentSearchMatch, AgentSearchResult, AgentWatchEvent, AgentWatchStartResult, AgentWatchPollResult, AgentWatchStopResult, AgentCapabilities, AgentHelloExtras } from './agent-protocol-types.ts';
|
|
12
|
-
export declare const AGENT_MAX_JOB_WAIT_MS = 30000;
|
|
13
|
-
/**
|
|
14
|
-
* Add `waitMs` to a `proc.*` request only when it is positive.
|
|
15
|
-
*
|
|
16
|
-
* Omitted means "answer immediately", which is what an agent that predates the field does anyway —
|
|
17
|
-
* so a client that never passes a wait is byte-for-byte the pre-long-poll request.
|
|
18
|
-
*
|
|
19
|
-
* @param params - the method's own parameters.
|
|
20
|
-
* @param waitMs - requested server-side wait, or `undefined` for none.
|
|
21
|
-
* @returns the parameters to send.
|
|
22
|
-
*/
|
|
23
|
-
export declare function waitParams(params: Record<string, unknown>, waitMs: number | undefined): Record<string, unknown>;
|
|
24
|
-
/**
|
|
25
|
-
* Client deadline for a long-polled request.
|
|
26
|
-
*
|
|
27
|
-
* The server may legitimately block for `waitMs`, so the request budget must outlive it: a per-request
|
|
28
|
-
* deadline here is **fatal** to the whole connection (see `isFatalAgentFailure`), so an under-sized
|
|
29
|
-
* budget would turn a normal wait into a reconnect.
|
|
30
|
-
*
|
|
31
|
-
* @param waitMs - requested server-side wait, or `undefined` for none.
|
|
32
|
-
* @returns the request budget, or `undefined` to keep the transport default.
|
|
33
|
-
*/
|
|
34
|
-
export declare function waitBudget(waitMs: number | undefined): number | undefined;
|
|
35
|
-
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
36
|
-
/** Read the `capabilities` object out of a `hello`/`capabilities` result, dropping wrong-typed fields. */
|
|
37
|
-
export declare function readAgentCaps(result: Record<string, unknown> | undefined): AgentCapabilities | undefined;
|
|
38
|
-
/** Read the `agent` object of a `hello` result. */
|
|
39
|
-
export declare function readAgentExtras(result: Record<string, unknown> | undefined): AgentHelloExtras;
|
|
40
|
-
/** Drop `undefined` request fields so a control frame stays minimal (and deterministic in tests). */
|
|
41
|
-
export declare function compactParams(request: ExecRequest): Readonly<Record<string, unknown>>;
|
|
42
|
-
/** Read a finite number field, or `null` when the agent sent nothing usable. */
|
|
43
|
-
export declare function readOptionalNumber(source: Record<string, unknown>, key: string): number | null;
|
|
44
|
-
/**
|
|
45
|
-
* A boolean field, falling back only when the field is **absent**.
|
|
46
|
-
*
|
|
47
|
-
* `??`-style semantics rather than `||`: an explicit `false` from the agent is a real answer ("this stream
|
|
48
|
-
* was not cut") and must not be replaced by the fallback. Using `||` here would silently convert every
|
|
49
|
-
* `false` into the legacy value, which is exactly how a complete stderr gets reported as truncated.
|
|
50
|
-
*/
|
|
51
|
-
export declare function booleanOr(value: unknown, fallback: boolean): boolean;
|
|
52
|
-
/** A non-empty string field, else `undefined` (an empty spill path is not a readable path). */
|
|
53
|
-
export declare function nonEmptyString(value: unknown): string | undefined;
|
|
54
|
-
/**
|
|
55
|
-
* Convert Unix nanoseconds from the wire into epoch milliseconds.
|
|
56
|
-
*
|
|
57
|
-
* @returns `null` when the agent sent nothing usable, so a caller can tell "no timestamp" apart from
|
|
58
|
-
* "the epoch". A negative value is passed through as a negative time rather than clamped.
|
|
59
|
-
*/
|
|
60
|
-
export declare function nsToMs(value: number | null): number | null;
|
|
61
|
-
/** Narrow a `proc.*` job status; unknown fields are dropped, missing numbers become 0. */
|
|
62
|
-
export declare function readJobStatus(raw: unknown): AgentJobStatus;
|
|
63
|
-
/** Narrow a `proc.output` result. */
|
|
64
|
-
export declare function readJobOutput(raw: unknown): AgentJobOutput;
|
|
65
|
-
/** Narrow an `lsp.*` session status. */
|
|
66
|
-
export declare function readLspStatus(raw: unknown): AgentLspStatus;
|
|
67
|
-
/** Narrow an `lsp.read` result. */
|
|
68
|
-
export declare function readLspRead(raw: unknown): AgentLspRead;
|
|
69
|
-
/**
|
|
70
|
-
* Build the `proc.start` frame.
|
|
71
|
-
*
|
|
72
|
-
* Everything the caller omits is **omitted**, not defaulted: the agent's own defaults apply. The one
|
|
73
|
-
* conversion is `stdinBytes` → base64, because the wire has no byte type.
|
|
74
|
-
*/
|
|
75
|
-
export declare function compactProcParams(request: AgentProcStartRequest): Record<string, unknown>;
|
|
76
|
-
/** Build the `lsp.start` frame, omitting what the caller did not set. */
|
|
77
|
-
export declare function compactLspParams(request: AgentLspStartRequest): Record<string, unknown>;
|
|
78
|
-
/** Narrow one `index.scan` entry (`{path,size,mtimeNs,isDir?}`); unknown fields are dropped. */
|
|
79
|
-
export declare function readIndexEntry(value: unknown): AgentIndexEntry;
|
|
80
|
-
/**
|
|
81
|
-
* Narrow one `index.scan` result.
|
|
82
|
-
*
|
|
83
|
-
* Defaults follow the protocol: `strategy` `"unknown"` when the agent sent nothing usable (an unknown
|
|
84
|
-
* strategy is *not* silently mapped onto a known one), `filesScanned` `0`, `warnings` empty, and
|
|
85
|
-
* `truncated` `false` — the last one is the only optimistic default in this block, and it means
|
|
86
|
-
* "the agent did not report truncation", not "the result is complete".
|
|
87
|
-
*/
|
|
88
|
-
export declare function readIndexScanResult(value: unknown): AgentIndexScanResult;
|
|
89
|
-
/** Narrow one `search.grep` match; `column` defaults to `0` and the context arrays to empty. */
|
|
90
|
-
export declare function readSearchMatch(value: unknown): AgentSearchMatch;
|
|
91
|
-
/**
|
|
92
|
-
* Narrow one `search.grep` result.
|
|
93
|
-
*
|
|
94
|
-
* `dropped` is not a `search.grep` field in protocol v1; it is left at `0` and documented as
|
|
95
|
-
* meaningless here rather than being invented from `truncated`.
|
|
96
|
-
*/
|
|
97
|
-
export declare function readSearchResult(value: unknown): AgentSearchResult;
|
|
98
|
-
/** Narrow one `watch.start` result; `watched` lists the **roots** the agent really registered. */
|
|
99
|
-
export declare function readWatchStartResult(value: unknown): AgentWatchStartResult;
|
|
100
|
-
/** Narrow one `watch.poll` event; `atNs` is converted to `atMs`. */
|
|
101
|
-
export declare function readWatchEvent(value: unknown): AgentWatchEvent;
|
|
102
|
-
/**
|
|
103
|
-
* Narrow one `watch.poll` result.
|
|
104
|
-
*
|
|
105
|
-
* `dropped` is passed through untouched because it is **cumulative**; the client never derives a delta
|
|
106
|
-
* from it (doing so would under-report drops exactly when the stream is already incomplete).
|
|
107
|
-
*/
|
|
108
|
-
export declare function readWatchPollResult(value: unknown): AgentWatchPollResult;
|
|
109
|
-
/** Narrow one `watch.stop` result; a missing `stopped` counts as `false`, which is not a failure. */
|
|
110
|
-
export declare function readWatchStopResult(value: unknown): AgentWatchStopResult;
|
|
111
|
-
/**
|
|
112
|
-
* Drop `undefined` request fields so a control frame stays minimal (and deterministic in tests).
|
|
113
|
-
*
|
|
114
|
-
* The same rule is applied inline by `search.grep` / `watch.*`: an omitted option means "let the agent
|
|
115
|
-
* use its own default", never "send this client's idea of the default". Only `index.scan` needs a helper
|
|
116
|
-
* because it has more optional fields than the others put together.
|
|
117
|
-
*/
|
|
118
|
-
export declare function compactIndexParams(request: AgentIndexScanRequest): Readonly<Record<string, unknown>>;
|
|
119
|
-
/**
|
|
120
|
-
* The agent transport: one stdio session, serialised requests, explicit degradation.
|
|
121
|
-
*
|
|
122
|
-
* Lifecycle matches the other two implementations (`idle` → `connecting` → `ready`, `lost` on an
|
|
123
|
-
* unexpected death) so callers cannot tell them apart except through `id` and `capabilities`.
|
|
124
|
-
*/
|
|
125
|
-
/**
|
|
126
|
-
* Whether a plugin error means the frame stream can no longer be trusted.
|
|
127
|
-
*
|
|
128
|
-
* Only these close the connection: everything else (a missing file, a stale version, an unsupported
|
|
129
|
-
* method) is a normal answered request and leaves the session healthy.
|
|
130
|
-
*/
|
|
131
|
-
//# sourceMappingURL=agent-protocol-codec.d.ts.map
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 代理协议的**错误与截止层**:错误归一、请求取消/超时、致命失败判定。
|
|
3
|
-
*
|
|
4
|
-
* 从 `agent-protocol-client.ts` 拆出(审计 0079)。客户端与传输层都需要"这个失败还要不要继续",
|
|
5
|
-
* 判定放在这里,避免两边各写一份。
|
|
6
|
-
*
|
|
7
|
-
* @module dsh-remote-workspace/infra/transport/agent-protocol-errors
|
|
8
|
-
*/
|
|
9
|
-
import { SshDevError } from '../../domain/errors.ts';
|
|
10
|
-
export declare function toSshDev(error: unknown, method: string): SshDevError;
|
|
11
|
-
/** Internal marker: the caller's signal aborted while waiting. */
|
|
12
|
-
export declare class RequestAbortedError extends Error {
|
|
13
|
-
}
|
|
14
|
-
/** Internal marker: the per-request deadline expired. */
|
|
15
|
-
export declare class RequestTimeoutError extends Error {
|
|
16
|
-
readonly timeoutMs: number;
|
|
17
|
-
constructor(timeoutMs: number);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Await `promise` under a deadline and an abort signal.
|
|
21
|
-
*
|
|
22
|
-
* The timer is always cleared and the abort listener always removed, so no path leaves a dangling
|
|
23
|
-
* handle behind; the first settlement wins. `onTimeout` / `onAbort` let a caller name the error that
|
|
24
|
-
* fits its context (a request deadline versus a missing blob frame).
|
|
25
|
-
*/
|
|
26
|
-
export declare function withDeadlineAndAbort<T>(promise: Promise<T>, options: {
|
|
27
|
-
readonly signal?: AbortSignal;
|
|
28
|
-
readonly timeoutMs: number;
|
|
29
|
-
readonly method: string;
|
|
30
|
-
readonly onTimeout?: (timeoutMs: number) => Error;
|
|
31
|
-
readonly onAbort?: () => Error;
|
|
32
|
-
}): {
|
|
33
|
-
readonly promise: Promise<T>;
|
|
34
|
-
readonly cancel: () => void;
|
|
35
|
-
};
|
|
36
|
-
/** Largest server-side wait the agent accepts for `proc.status` / `proc.output` (`waitMs`).
|
|
37
|
-
*
|
|
38
|
-
* Distinct from `MAX_JOB_WAIT_MS` in `remote-job-tools.ts`: that one is the **client's** overall wait budget
|
|
39
|
-
* (10 min); this one is the **server's** single-request cap (30 s). */
|
|
40
|
-
export declare function isFatalAgentFailure(error: SshDevError): boolean;
|
|
41
|
-
//# sourceMappingURL=agent-protocol-errors.d.ts.map
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 代理协议的**帧层**:常量、错误类型、JSON/Blob 帧编解码、流式解析器与错误映射。
|
|
3
|
-
*
|
|
4
|
-
* 从 `agent-transport.ts` 拆出(审计 0077):这一层只关心字节与帧,不知道连接、会话或传输。
|
|
5
|
-
* 边界由用户要求先定:**协议层(帧/类型/客户端)与传输适配层分开**。
|
|
6
|
-
*
|
|
7
|
-
* @module dsh-remote-workspace/infra/transport/agent-protocol-frames
|
|
8
|
-
*/
|
|
9
|
-
import { SshDevError } from '../../domain/errors.ts';
|
|
10
|
-
/**
|
|
11
|
-
* The `agent` transport (Tier 2): the plugin side of the self-hosted Go remote agent.
|
|
12
|
-
*
|
|
13
|
-
* Why a third implementation exists at all: the zero-install floor (Tier 1: plain POSIX commands over
|
|
14
|
-
* `ssh`) cannot provide native file watching, server-side indexing, or long tasks. The optional agent
|
|
15
|
-
* binary adds them *without* becoming a requirement — when it is missing, outdated, or refuses the
|
|
16
|
-
* handshake, the caller falls back to Tier 1 instead of degrading silently.
|
|
17
|
-
*
|
|
18
|
-
* Deployment constraints this module is written against:
|
|
19
|
-
*
|
|
20
|
-
* - the agent is an **optional** single static binary (`doc/02-platform/zero-install-boundaries.md`);
|
|
21
|
-
* - it speaks only over the **stdio channel** of an `ssh` command (`ssh <alias> <agent> --stdio`),
|
|
22
|
-
* listening on no port (`doc/02-platform/remote-footprint.md`);
|
|
23
|
-
* - the wire protocol is a **single evolving spec** (`dsh-ssh-agent/doc/01-product/protocol.md`); there is no
|
|
24
|
-
* frozen/next split, so the frame codec below follows that file field by field instead of inventing a
|
|
25
|
-
* friendlier one — and when that file changes, this codec changes with it in the same round.
|
|
26
|
-
*
|
|
27
|
-
* Three consequences of the current wire shape are visible in this file and are **not** temporary
|
|
28
|
-
* workarounds to be "cleaned up" later:
|
|
29
|
-
*
|
|
30
|
-
* 1. **there is no arbitrary command execution in the protocol's core surface.** The agent's method
|
|
31
|
-
* dispatch serves `proc.exec` only when the capability bit says so (verified by reading
|
|
32
|
-
* `internal/agent/server.go`), so {@link AgentTransport.exec} needs
|
|
33
|
-
* an injected {@link AgentExecCommand}; without one it asks `proc.exec` and turns `E_METHOD` into
|
|
34
|
-
* `REMOTE_UNSUPPORTED` with a message saying this agent version cannot run commands.
|
|
35
|
-
* 2. **`fs.write` has `expectedVersion` but no digest.** The `Transport` contract's
|
|
36
|
-
* `expectedSha256` is therefore honoured as a *version* guard (stat, compare, then write with the
|
|
37
|
-
* same version as `expectedVersion`) — never as a digest guard — and that distinction is reported.
|
|
38
|
-
* 3. **a control frame is paired with its blob by *order*, not by id.** ADR-0009 made the agent dispatch
|
|
39
|
-
* requests concurrently, so responses may arrive out of order; what the agent still guarantees is
|
|
40
|
-
* that a response and the blob it declared are written back-to-back inside one critical section. Blob
|
|
41
|
-
* frames therefore arrive in the same order as the responses that declared them, which is what lets
|
|
42
|
-
* this client pipeline up to {@link DEFAULT_AGENT_MAX_IN_FLIGHT} requests while pairing each blob with
|
|
43
|
-
* its own request (see {@link AgentProtocolClient}).
|
|
44
|
-
*
|
|
45
|
-
* No third-party dependency is involved: the session is injected (`AgentLauncher`), so every unit test
|
|
46
|
-
* runs against an in-memory fake and `node:child_process` is only reached by {@link defaultLauncher}.
|
|
47
|
-
*
|
|
48
|
-
* @module dsh-remote-workspace/infra/transport/agent-transport
|
|
49
|
-
*/
|
|
50
|
-
/** Protocol version this client speaks; must equal the agent's `protocol.ProtocolVersion`. */
|
|
51
|
-
export declare const AGENT_PROTOCOL_VERSION = 1;
|
|
52
|
-
/** Client identifier sent in `hello.params.client`; diagnostic only, the agent never branches on it. */
|
|
53
|
-
export declare const AGENT_CLIENT_ID = "dsh-remote-workspace/0.1.0";
|
|
54
|
-
/** Single-frame payload ceiling, mirrored from the agent's `protocol.MaxFrameBytes` (16 MiB). */
|
|
55
|
-
export declare const MAX_AGENT_FRAME_BYTES: number;
|
|
56
|
-
/** Frame kind byte: control frame carrying one JSON request or one JSON response. */
|
|
57
|
-
export declare const AGENT_KIND_JSON = 74;
|
|
58
|
-
/** Frame kind byte: binary data frame (file content), sent only after a blob-declaring control frame. */
|
|
59
|
-
export declare const AGENT_KIND_BLOB = 66;
|
|
60
|
-
/**
|
|
61
|
-
* The watcher name the agent uses when a caller omits `watcherId`.
|
|
62
|
-
*
|
|
63
|
-
* Mirrors the agent's `watch.DefaultWatcherID`. Kept client-side so a result from an agent that predates
|
|
64
|
-
* the `watcherId` echo still reports which watcher it actually touched (that agent had exactly one).
|
|
65
|
-
*/
|
|
66
|
-
export declare const DEFAULT_AGENT_WATCHER_ID = "default";
|
|
67
|
-
/** Default per-request deadline used when the caller names none. */
|
|
68
|
-
export declare const DEFAULT_AGENT_REQUEST_TIMEOUT_MS = 15000;
|
|
69
|
-
/**
|
|
70
|
-
* How many requests the client may keep in flight on one connection.
|
|
71
|
-
*
|
|
72
|
-
* Mirrors the agent's own `MaxInFlightRequests` (8): the agent acquires one slot per request *in its read
|
|
73
|
-
* goroutine*, so sending more than that would stall its reads instead of buying throughput. Staying at the
|
|
74
|
-
* agent's limit keeps the pipeline full without ever blocking the peer's reader.
|
|
75
|
-
*/
|
|
76
|
-
export declare const DEFAULT_AGENT_MAX_IN_FLIGHT = 8;
|
|
77
|
-
/**
|
|
78
|
-
* Default agent mode flag.
|
|
79
|
-
*
|
|
80
|
-
* `--shared` lets one resident agent process serve many sessions (shared jobs / LSP / index snapshots)
|
|
81
|
-
* and falls back to the in-process loop when a daemon is unavailable. `--stdio` pins the old
|
|
82
|
-
* one-process-per-connection behaviour, which tests and diagnostics still use.
|
|
83
|
-
*/
|
|
84
|
-
export declare const DEFAULT_AGENT_MODE = "--shared";
|
|
85
|
-
/** The pinned in-process mode (one agent process per connection). */
|
|
86
|
-
export declare const STDIO_AGENT_MODE = "--stdio";
|
|
87
|
-
/** A structured failure reported by the agent (or synthesised by this client). */
|
|
88
|
-
export declare class AgentProtocolError extends Error {
|
|
89
|
-
readonly code: string;
|
|
90
|
-
readonly details: Readonly<Record<string, unknown>>;
|
|
91
|
-
constructor(code: string, message: string, details?: Readonly<Record<string, unknown>>);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* The narrow view of one agent session this module needs.
|
|
95
|
-
*
|
|
96
|
-
* Deliberately tiny so a fake is trivial and so the module never touches `node:child_process` itself:
|
|
97
|
-
* `onData` delivers stdout bytes **in arrival order** (frame boundaries are not preserved), `onExit`
|
|
98
|
-
* fires once when the remote process is gone.
|
|
99
|
-
*/
|
|
100
|
-
export interface AgentFrame {
|
|
101
|
-
/** Kind byte: {@link AGENT_KIND_JSON} or {@link AGENT_KIND_BLOB}. */
|
|
102
|
-
readonly kind: number;
|
|
103
|
-
/** Payload bytes, copied out of the transport buffer. */
|
|
104
|
-
readonly payload: Uint8Array;
|
|
105
|
-
}
|
|
106
|
-
/** One encoded frame, split into its two written halves. */
|
|
107
|
-
export interface EncodedFrame {
|
|
108
|
-
/** The 5-byte `[kind][uint32 BE length]` header. */
|
|
109
|
-
readonly header: Uint8Array;
|
|
110
|
-
/** The payload (`header[4]` is its length). */
|
|
111
|
-
readonly payload: Uint8Array;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Encode one frame: `[1B kind][4B BE length][payload]`.
|
|
115
|
-
*
|
|
116
|
-
* @throws AgentProtocolError `E_PROTOCOL` for an unknown kind byte.
|
|
117
|
-
* @throws AgentProtocolError `E_TOO_LARGE` when the payload exceeds {@link MAX_AGENT_FRAME_BYTES}.
|
|
118
|
-
*/
|
|
119
|
-
export declare function encodeFrame(kind: number, payload: Uint8Array): EncodedFrame;
|
|
120
|
-
/** Encode one complete frame (header immediately followed by payload). */
|
|
121
|
-
export declare function encodeFrameBytes(kind: number, payload: Uint8Array): Uint8Array;
|
|
122
|
-
/**
|
|
123
|
-
* Decode exactly one frame from the head of `bytes`.
|
|
124
|
-
*
|
|
125
|
-
* @returns the frame plus `consumed` (header + payload) bytes, or `null` when the buffer holds only
|
|
126
|
-
* part of a frame — callers keep the remainder and retry, which is how a chunked stream is framed.
|
|
127
|
-
* @throws AgentProtocolError `E_PROTOCOL` for an illegal kind byte; `E_TOO_LARGE` when the declared
|
|
128
|
-
* length exceeds the ceiling (rejected before allocating, exactly like the agent's own reader).
|
|
129
|
-
*/
|
|
130
|
-
export declare function decodeFrame(bytes: Uint8Array): {
|
|
131
|
-
readonly frame: AgentFrame;
|
|
132
|
-
readonly consumed: number;
|
|
133
|
-
} | null;
|
|
134
|
-
/**
|
|
135
|
-
* Incremental frame decoder over a byte stream that arrives in arbitrary chunks.
|
|
136
|
-
*
|
|
137
|
-
* **Why it keeps a read cursor instead of trimming the buffer on every frame.** The obvious implementation
|
|
138
|
-
* (`buffer = concat(buffer, chunk)` then `buffer = buffer.slice(consumed)` per frame) re-copies the whole
|
|
139
|
-
* remaining payload once per chunk *and* once per frame, so a body that arrives in many small pieces costs
|
|
140
|
-
* O(bytes x pieces). Measured on this repository: an 8 MiB blob delivered in 64 KiB chunks spent **142 ms**
|
|
141
|
-
* of synchronous main-thread time versus **5.1 ms** when it arrived in one piece (audit 0043) — and doubling
|
|
142
|
-
* the number of chunks doubled the cost, which is the signature of the quadratic term. Every one of those
|
|
143
|
-
* milliseconds is a stalled event loop, i.e. a stalled GUI.
|
|
144
|
-
*
|
|
145
|
-
* Two changes were needed, and the measurement is what proved the first one alone was **not** enough:
|
|
146
|
-
*
|
|
147
|
-
* 1. the frame loop reads through a window (`#start`/`#end` over one store) instead of copying the remainder
|
|
148
|
-
* per frame;
|
|
149
|
-
* 2. the store grows **geometrically** (doubling) instead of being reallocated at exactly `pending + chunk`
|
|
150
|
-
* on every chunk.
|
|
151
|
-
*
|
|
152
|
-
* (1) alone still measured 126 ms: an exactly-sized `Uint8Array` per 64 KiB chunk copies the whole body every
|
|
153
|
-
* time, so the cost stays O(bytes x chunks). With both, the same 8 MiB body measured **9.3 ms** and the cost
|
|
154
|
-
* became flat in the chunk size (9.3 / 10.3 / 7.3 / 5.5 ms for 64 KiB … 8 MiB chunks) — linear, where before
|
|
155
|
-
* doubling the chunk count doubled the time. Both changes matter; neither is sufficient alone.
|
|
156
|
-
*/
|
|
157
|
-
export declare class AgentFrameParser {
|
|
158
|
-
#private;
|
|
159
|
-
/**
|
|
160
|
-
* Feed one chunk; returns every frame that became complete, in arrival order.
|
|
161
|
-
*
|
|
162
|
-
* @param chunk - the bytes that just arrived; any split point is legal.
|
|
163
|
-
* @returns the complete frames, in arrival order.
|
|
164
|
-
*/
|
|
165
|
-
push(chunk: Uint8Array): readonly AgentFrame[];
|
|
166
|
-
/** Bytes retained for an incomplete frame (0 when the stream is aligned). */
|
|
167
|
-
get pendingBytes(): number;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Map an agent error code onto a plugin error code.
|
|
171
|
-
*
|
|
172
|
-
* Centralised on purpose: this table is part of the contract with the agent, and every entry is
|
|
173
|
-
* asserted by `tests/agent-transport.test.ts`.
|
|
174
|
-
*
|
|
175
|
-
* Two entries deserve their reasoning stated:
|
|
176
|
-
*
|
|
177
|
-
* - `E_HANDSHAKE` / `E_PROTOCOL` mean "this stream cannot be trusted" (wrong protocol version, frames
|
|
178
|
-
* out of order), so they surface as `CONNECTION_LOST`: the connection is unusable, not the request.
|
|
179
|
-
* - `E_TOO_LARGE` is **one code with two meanings**, so it is mapped by `details.scope`:
|
|
180
|
-
* a **size** limit (`scope: "size"`, or absent on an older agent) becomes `REMOTE_UNSUPPORTED`
|
|
181
|
-
* because v1 has no chunked read to fall back on — the request itself is too big;
|
|
182
|
-
* a **capacity** limit (`scope: "session" | "job" | "lsp" | "watcher"`) becomes
|
|
183
|
-
* `REMOTE_COMMAND_FAILED`, because nothing is wrong with the request — the remote is momentarily
|
|
184
|
-
* full and retrying later is the right move.
|
|
185
|
-
*
|
|
186
|
-
* Why the split matters: mapping capacity exhaustion to `REMOTE_UNSUPPORTED` used to make it reach
|
|
187
|
-
* the filesystem layer as `FS_NOT_REGULAR_FILE` ("this is not a regular file"), which points a
|
|
188
|
-
* caller at the wrong thing entirely. Measured end to end (`.verify/stage8-too-large-conflation.mjs`):
|
|
189
|
-
* 200 slow requests on one session ⇒ 128 rejected with `E_TOO_LARGE` + `scope: "session"` ⇒
|
|
190
|
-
* surfaced as `FS_NOT_REGULAR_FILE`.
|
|
191
|
-
*
|
|
192
|
-
* An unrecognised code (a newer agent) is reported as `REMOTE_COMMAND_FAILED` with the original code
|
|
193
|
-
* kept in `details.agentCode`, so a new agent error is never silently mistranslated into a known one.
|
|
194
|
-
*/
|
|
195
|
-
export declare function agentErrorToSshDev(error: AgentProtocolError, connectionId: string): SshDevError;
|
|
196
|
-
/** Client-side default for `index.scan` `maxEntries`; mirrors the agent's `index.DefaultMaxEntries`. */
|
|
197
|
-
//# sourceMappingURL=agent-protocol-frames.d.ts.map
|