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
package/lib/terminal-wrapper.js
CHANGED
|
@@ -20,9 +20,9 @@ var SshDevError = class extends Error {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
// src/
|
|
23
|
+
// src/shared/root-keys.ts
|
|
24
24
|
function normalizeLocalPath(path, options = {}) {
|
|
25
|
-
const caseInsensitive = options.caseInsensitive ??
|
|
25
|
+
const caseInsensitive = options.caseInsensitive ?? false;
|
|
26
26
|
const unified = path.replace(/\\/g, "/");
|
|
27
27
|
const unc = unified.startsWith("//");
|
|
28
28
|
const posixAbsolute = unified.startsWith("/");
|
|
@@ -47,9 +47,14 @@ function normalizeLocalPath(path, options = {}) {
|
|
|
47
47
|
else normalized = body === "" ? "." : body;
|
|
48
48
|
return caseInsensitive ? normalized.toLowerCase() : normalized;
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
// src/host/domain/roots/root.ts
|
|
52
|
+
function normalizeLocalPath2(path, options = {}) {
|
|
53
|
+
return normalizeLocalPath(path, { caseInsensitive: options.caseInsensitive ?? process.platform === "win32" });
|
|
54
|
+
}
|
|
50
55
|
function localPathContains(root, candidate, options = {}) {
|
|
51
|
-
const normalizedRoot =
|
|
52
|
-
const normalizedCandidate =
|
|
56
|
+
const normalizedRoot = normalizeLocalPath2(root, options);
|
|
57
|
+
const normalizedCandidate = normalizeLocalPath2(candidate, options);
|
|
53
58
|
if (normalizedRoot === "/" || /^[a-z]:\/$/.test(normalizedRoot)) {
|
|
54
59
|
return normalizedCandidate.startsWith(normalizedRoot);
|
|
55
60
|
}
|
|
@@ -84,7 +84,27 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
84
84
|
*/
|
|
85
85
|
readCacheTtlMs: z<number, number, "defined">;
|
|
86
86
|
readCacheMaxEntries: z<number, number, "defined">;
|
|
87
|
+
/**
|
|
88
|
+
* Byte ceiling for the read cache of **one remote root**, not for the plugin as a whole.
|
|
89
|
+
*
|
|
90
|
+
* 这条的语义必须写清楚,否则会读成"整个插件的上限":每个远端根各自持有一份版本缓存(外加一份
|
|
91
|
+
* 目录列举缓存),所以 N 个**同时存在**的根是 N × 这个数。上界因此是"活根数"而不是"历史根数"——
|
|
92
|
+
* 根被移除时 `Backend.dispose()` 会把它的缓存一起释放(审计 0112 P3-11 接线之前不是这样,
|
|
93
|
+
* 那才是 P3-12 真正的风险所在)。要压总占用就调小这个数,或者减少同时挂着的远端根。
|
|
94
|
+
*/
|
|
87
95
|
readCacheMaxBytes: z<number, number, "defined">;
|
|
96
|
+
/**
|
|
97
|
+
* Ceiling for the **sum** over every remote root's caches, not per root.
|
|
98
|
+
*
|
|
99
|
+
* 0112 P3-12 的缺口是"每个根各自封顶、加起来没人管":`readCacheMaxBytes` 是每根的额度,
|
|
100
|
+
* 十根就是十倍。这一项把总和钉住——超过时由**占用最大的那个**缓存让出最旧的条目(通常也是读者
|
|
101
|
+
* 正在看的那个,所以不让刚写的先挨刀)。
|
|
102
|
+
*
|
|
103
|
+
* 默认 64 MiB ≈ 8 个满额度的根。**必须是正整数**:要彻底关掉缓存请设
|
|
104
|
+
* `readCacheMaxBytes: 0`(那是"根本不缓存"),而不是把总预算设为 0——后者只会让每次写入
|
|
105
|
+
* 立刻把自己的条目淘汰掉,行为既不是"关缓存"也不是"缓存"。
|
|
106
|
+
*/
|
|
107
|
+
readCacheTotalMaxBytes: z<number, number, "defined">;
|
|
88
108
|
terminalStateDir: z<string, string, "plain">;
|
|
89
109
|
transferChunkBytes: z<number, number, "defined">;
|
|
90
110
|
/** Chunks in flight at once during a transfer. 1 restores the sequential behaviour. */
|
|
@@ -110,8 +130,6 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
110
130
|
sessionBinMaxEntries: z<number, number, "defined">;
|
|
111
131
|
sessionBinMaxBytes: z<number, number, "defined">;
|
|
112
132
|
sessionBinMaxAgeMs: z<number, number, "defined">;
|
|
113
|
-
/** Delete the projection cache alongside the log when true (FR-3.4 step 8). */
|
|
114
|
-
sessionPurgeProjection: z<boolean, boolean, "defined">;
|
|
115
133
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
116
134
|
maxReadBytes: z<number, number, "defined">;
|
|
117
135
|
connectTimeoutMs: z<number, number, "defined">;
|
|
@@ -133,7 +151,27 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
133
151
|
*/
|
|
134
152
|
readCacheTtlMs: z<number, number, "defined">;
|
|
135
153
|
readCacheMaxEntries: z<number, number, "defined">;
|
|
154
|
+
/**
|
|
155
|
+
* Byte ceiling for the read cache of **one remote root**, not for the plugin as a whole.
|
|
156
|
+
*
|
|
157
|
+
* 这条的语义必须写清楚,否则会读成"整个插件的上限":每个远端根各自持有一份版本缓存(外加一份
|
|
158
|
+
* 目录列举缓存),所以 N 个**同时存在**的根是 N × 这个数。上界因此是"活根数"而不是"历史根数"——
|
|
159
|
+
* 根被移除时 `Backend.dispose()` 会把它的缓存一起释放(审计 0112 P3-11 接线之前不是这样,
|
|
160
|
+
* 那才是 P3-12 真正的风险所在)。要压总占用就调小这个数,或者减少同时挂着的远端根。
|
|
161
|
+
*/
|
|
136
162
|
readCacheMaxBytes: z<number, number, "defined">;
|
|
163
|
+
/**
|
|
164
|
+
* Ceiling for the **sum** over every remote root's caches, not per root.
|
|
165
|
+
*
|
|
166
|
+
* 0112 P3-12 的缺口是"每个根各自封顶、加起来没人管":`readCacheMaxBytes` 是每根的额度,
|
|
167
|
+
* 十根就是十倍。这一项把总和钉住——超过时由**占用最大的那个**缓存让出最旧的条目(通常也是读者
|
|
168
|
+
* 正在看的那个,所以不让刚写的先挨刀)。
|
|
169
|
+
*
|
|
170
|
+
* 默认 64 MiB ≈ 8 个满额度的根。**必须是正整数**:要彻底关掉缓存请设
|
|
171
|
+
* `readCacheMaxBytes: 0`(那是"根本不缓存"),而不是把总预算设为 0——后者只会让每次写入
|
|
172
|
+
* 立刻把自己的条目淘汰掉,行为既不是"关缓存"也不是"缓存"。
|
|
173
|
+
*/
|
|
174
|
+
readCacheTotalMaxBytes: z<number, number, "defined">;
|
|
137
175
|
terminalStateDir: z<string, string, "plain">;
|
|
138
176
|
transferChunkBytes: z<number, number, "defined">;
|
|
139
177
|
/** Chunks in flight at once during a transfer. 1 restores the sequential behaviour. */
|
|
@@ -159,8 +197,6 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
159
197
|
sessionBinMaxEntries: z<number, number, "defined">;
|
|
160
198
|
sessionBinMaxBytes: z<number, number, "defined">;
|
|
161
199
|
sessionBinMaxAgeMs: z<number, number, "defined">;
|
|
162
|
-
/** Delete the projection cache alongside the log when true (FR-3.4 step 8). */
|
|
163
|
-
sessionPurgeProjection: z<boolean, boolean, "defined">;
|
|
164
200
|
}>>, "defined">;
|
|
165
201
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
166
202
|
connections: z<({
|
|
@@ -228,7 +264,27 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
228
264
|
*/
|
|
229
265
|
readCacheTtlMs: z<number, number, "defined">;
|
|
230
266
|
readCacheMaxEntries: z<number, number, "defined">;
|
|
267
|
+
/**
|
|
268
|
+
* Byte ceiling for the read cache of **one remote root**, not for the plugin as a whole.
|
|
269
|
+
*
|
|
270
|
+
* 这条的语义必须写清楚,否则会读成"整个插件的上限":每个远端根各自持有一份版本缓存(外加一份
|
|
271
|
+
* 目录列举缓存),所以 N 个**同时存在**的根是 N × 这个数。上界因此是"活根数"而不是"历史根数"——
|
|
272
|
+
* 根被移除时 `Backend.dispose()` 会把它的缓存一起释放(审计 0112 P3-11 接线之前不是这样,
|
|
273
|
+
* 那才是 P3-12 真正的风险所在)。要压总占用就调小这个数,或者减少同时挂着的远端根。
|
|
274
|
+
*/
|
|
231
275
|
readCacheMaxBytes: z<number, number, "defined">;
|
|
276
|
+
/**
|
|
277
|
+
* Ceiling for the **sum** over every remote root's caches, not per root.
|
|
278
|
+
*
|
|
279
|
+
* 0112 P3-12 的缺口是"每个根各自封顶、加起来没人管":`readCacheMaxBytes` 是每根的额度,
|
|
280
|
+
* 十根就是十倍。这一项把总和钉住——超过时由**占用最大的那个**缓存让出最旧的条目(通常也是读者
|
|
281
|
+
* 正在看的那个,所以不让刚写的先挨刀)。
|
|
282
|
+
*
|
|
283
|
+
* 默认 64 MiB ≈ 8 个满额度的根。**必须是正整数**:要彻底关掉缓存请设
|
|
284
|
+
* `readCacheMaxBytes: 0`(那是"根本不缓存"),而不是把总预算设为 0——后者只会让每次写入
|
|
285
|
+
* 立刻把自己的条目淘汰掉,行为既不是"关缓存"也不是"缓存"。
|
|
286
|
+
*/
|
|
287
|
+
readCacheTotalMaxBytes: z<number, number, "defined">;
|
|
232
288
|
terminalStateDir: z<string, string, "plain">;
|
|
233
289
|
transferChunkBytes: z<number, number, "defined">;
|
|
234
290
|
/** Chunks in flight at once during a transfer. 1 restores the sequential behaviour. */
|
|
@@ -254,8 +310,6 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
254
310
|
sessionBinMaxEntries: z<number, number, "defined">;
|
|
255
311
|
sessionBinMaxBytes: z<number, number, "defined">;
|
|
256
312
|
sessionBinMaxAgeMs: z<number, number, "defined">;
|
|
257
|
-
/** Delete the projection cache alongside the log when true (FR-3.4 step 8). */
|
|
258
|
-
sessionPurgeProjection: z<boolean, boolean, "defined">;
|
|
259
313
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
260
314
|
maxReadBytes: z<number, number, "defined">;
|
|
261
315
|
connectTimeoutMs: z<number, number, "defined">;
|
|
@@ -277,7 +331,27 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
277
331
|
*/
|
|
278
332
|
readCacheTtlMs: z<number, number, "defined">;
|
|
279
333
|
readCacheMaxEntries: z<number, number, "defined">;
|
|
334
|
+
/**
|
|
335
|
+
* Byte ceiling for the read cache of **one remote root**, not for the plugin as a whole.
|
|
336
|
+
*
|
|
337
|
+
* 这条的语义必须写清楚,否则会读成"整个插件的上限":每个远端根各自持有一份版本缓存(外加一份
|
|
338
|
+
* 目录列举缓存),所以 N 个**同时存在**的根是 N × 这个数。上界因此是"活根数"而不是"历史根数"——
|
|
339
|
+
* 根被移除时 `Backend.dispose()` 会把它的缓存一起释放(审计 0112 P3-11 接线之前不是这样,
|
|
340
|
+
* 那才是 P3-12 真正的风险所在)。要压总占用就调小这个数,或者减少同时挂着的远端根。
|
|
341
|
+
*/
|
|
280
342
|
readCacheMaxBytes: z<number, number, "defined">;
|
|
343
|
+
/**
|
|
344
|
+
* Ceiling for the **sum** over every remote root's caches, not per root.
|
|
345
|
+
*
|
|
346
|
+
* 0112 P3-12 的缺口是"每个根各自封顶、加起来没人管":`readCacheMaxBytes` 是每根的额度,
|
|
347
|
+
* 十根就是十倍。这一项把总和钉住——超过时由**占用最大的那个**缓存让出最旧的条目(通常也是读者
|
|
348
|
+
* 正在看的那个,所以不让刚写的先挨刀)。
|
|
349
|
+
*
|
|
350
|
+
* 默认 64 MiB ≈ 8 个满额度的根。**必须是正整数**:要彻底关掉缓存请设
|
|
351
|
+
* `readCacheMaxBytes: 0`(那是"根本不缓存"),而不是把总预算设为 0——后者只会让每次写入
|
|
352
|
+
* 立刻把自己的条目淘汰掉,行为既不是"关缓存"也不是"缓存"。
|
|
353
|
+
*/
|
|
354
|
+
readCacheTotalMaxBytes: z<number, number, "defined">;
|
|
281
355
|
terminalStateDir: z<string, string, "plain">;
|
|
282
356
|
transferChunkBytes: z<number, number, "defined">;
|
|
283
357
|
/** Chunks in flight at once during a transfer. 1 restores the sequential behaviour. */
|
|
@@ -303,10 +377,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
303
377
|
sessionBinMaxEntries: z<number, number, "defined">;
|
|
304
378
|
sessionBinMaxBytes: z<number, number, "defined">;
|
|
305
379
|
sessionBinMaxAgeMs: z<number, number, "defined">;
|
|
306
|
-
/** Delete the projection cache alongside the log when true (FR-3.4 step 8). */
|
|
307
|
-
sessionPurgeProjection: z<boolean, boolean, "defined">;
|
|
308
380
|
}>>, "defined">;
|
|
309
381
|
}>>, "plain">;
|
|
310
382
|
/** What {@link apply} receives: the schema's resolved output, which is what the loader passes. */
|
|
311
383
|
export type ResolvedConfig = Schemastery.TypeT<typeof Config>;
|
|
312
|
-
//# sourceMappingURL=config.d.ts.map
|
|
@@ -22,4 +22,3 @@ import { Context } from '@deepseek-ai/cordis';
|
|
|
22
22
|
*/
|
|
23
23
|
export default function apply(ctx: Context): (import("@deepseek-ai/cordis").Fiber & PromiseLike<import("@deepseek-ai/cordis").Fiber>) | undefined;
|
|
24
24
|
export { RemoteFileReferenceService, DEFAULT_MAX_RESULTS, LOCAL_EXCLUDED_DIRECTORIES, LOCAL_MAX_DEPTH, LOCAL_MAX_ENTRIES, type FileReferenceIndex, type LocalEntry, type RemoteFileReferenceOptions, } from './host/integration/fs/file-reference-provider.ts';
|
|
25
|
-
//# sourceMappingURL=file-references.d.ts.map
|
|
@@ -77,6 +77,15 @@ export interface Backend {
|
|
|
77
77
|
readonly sandboxMode: BackendSandboxMode | undefined;
|
|
78
78
|
/** Whether the backend can watch for changes natively. */
|
|
79
79
|
readonly watches: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Stop background work (watchers, poll loops) and release what this backend holds.
|
|
82
|
+
*
|
|
83
|
+
* Called when its root is retired. Optional: a backend with nothing to stop omits it. Without this call a
|
|
84
|
+
* removed root's watcher kept polling — `RemoteBackend.dispose()` existed but had **zero production callers**,
|
|
85
|
+
* so the poll loop outlived the root that started it and the remote inotify registration was never dropped
|
|
86
|
+
* (audit 0112 P3-11).
|
|
87
|
+
*/
|
|
88
|
+
dispose?(): Promise<void>;
|
|
80
89
|
/**
|
|
81
90
|
* Watch one path for changes, in this backend's own absolute spelling (the backend layer has no `FsTarget`).
|
|
82
91
|
*
|
|
@@ -167,4 +176,3 @@ export interface Backend {
|
|
|
167
176
|
/** `file:` URL for this path in the backend's world. */
|
|
168
177
|
fileUrl?(absolute: string): string;
|
|
169
178
|
}
|
|
170
|
-
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -42,4 +42,3 @@ export * from './recycle-bin-contract.ts';
|
|
|
42
42
|
* @returns a {@link RecycleBinService}; its undo stack is per-instance, in memory and not persisted.
|
|
43
43
|
*/
|
|
44
44
|
export declare function createRecycleBinService(deps: RecycleBinServiceDeps): RecycleBinService;
|
|
45
|
-
//# sourceMappingURL=recycle-bin-service.d.ts.map
|
|
@@ -94,6 +94,18 @@ export interface SessionAdminDeps {
|
|
|
94
94
|
readonly detachSession?: (sessionId: string) => Promise<void>;
|
|
95
95
|
/** Announce the removal so clients drop the row (`api-session/removed`). */
|
|
96
96
|
readonly emitRemoved?: (sessionId: string) => void;
|
|
97
|
+
/**
|
|
98
|
+
* The session is gone: drop it from any bookkeeping that remembers session ids.
|
|
99
|
+
*
|
|
100
|
+
* Fired **after** the deletion is durable, on both the permanent and the recycle path, and it is not awaited:
|
|
101
|
+
* losing a stale id in `user-roots.json` must not turn a completed deletion into a failure. The implementation
|
|
102
|
+
* is expected to be best-effort and to log its own warnings.
|
|
103
|
+
*
|
|
104
|
+
* Audit 0112 P3-13: before this, nothing told `user-roots.json` that a session had been deleted, so every root
|
|
105
|
+
* a session had added kept its dead id forever — the panel went on showing the root as "added by a session
|
|
106
|
+
* that no longer exists" and the file grew on every write.
|
|
107
|
+
*/
|
|
108
|
+
readonly onSessionRemoved?: (sessionId: string) => void;
|
|
97
109
|
/** Injected clock. */
|
|
98
110
|
readonly now: () => number;
|
|
99
111
|
/** Who confirmed, for the audit trail (FR-3.10); absent when the caller did not say. */
|
|
@@ -218,4 +230,3 @@ export interface SessionAdminService {
|
|
|
218
230
|
* @throws SshDevError `ROOT_INVALID` when the bin root is inside the sessions root (that placement breaks the
|
|
219
231
|
* platform's session listing — see the module note and ADR-0009).
|
|
220
232
|
*/
|
|
221
|
-
//# sourceMappingURL=session-admin-contract.d.ts.map
|
|
@@ -75,4 +75,3 @@ export declare function searchStrategyFor(capabilities: RemoteCapabilities): Sea
|
|
|
75
75
|
export declare function indexStrategyFor(capabilities: RemoteCapabilities): IndexStrategy;
|
|
76
76
|
/** Whether the host can run the plugin's file-transfer path. */
|
|
77
77
|
export declare function canTransferBytes(capabilities: RemoteCapabilities): boolean;
|
|
78
|
-
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -52,4 +52,3 @@ export declare function sshFailureToError(connectionId: string, input: {
|
|
|
52
52
|
}): SshDevError;
|
|
53
53
|
/** Keep only the tail of a long diagnostic string so details stay bounded. */
|
|
54
54
|
export declare function tail(text: string, maxChars: number): string;
|
|
55
|
-
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -103,4 +103,3 @@ export declare function validateConnectionProfile(input: unknown): ConnectionPro
|
|
|
103
103
|
export declare function profileFromImportDraft(id: string, draft: SshConfigImportDraft): ConnectionProfile;
|
|
104
104
|
/** One-line summary used by diagnostics and the settings list. */
|
|
105
105
|
export declare function connectionSummary(profile: ConnectionProfile): string;
|
|
106
|
-
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module dsh-over-ssh/domain/root
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import { isAbsoluteLocalPath, type RootKeyOptions, type RootLocation } from '../../../shared/root-keys.ts';
|
|
9
|
+
/** Where a root lives. The definition lives in `shared/root-keys.ts`, beside the key rule that needs it. */
|
|
10
|
+
export type { RootLocation };
|
|
10
11
|
/** One project root. */
|
|
11
12
|
export interface RootRef {
|
|
12
13
|
/** Local or remote. */
|
|
@@ -76,24 +77,39 @@ export declare function makeRemoteRoot(connectionId: string, remotePath: string,
|
|
|
76
77
|
* a child process receives via `processPath`.
|
|
77
78
|
*/
|
|
78
79
|
export declare function makeLocalRoot(path: string, options?: RootOptions): RootRef;
|
|
79
|
-
/**
|
|
80
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Whether a host path is absolute in either the Windows or the POSIX spelling.
|
|
82
|
+
*
|
|
83
|
+
* **Re-exported, not re-implemented.** The rule lives in `shared/root-keys.ts` because the client panel has to
|
|
84
|
+
* answer the same question before it sends a request — and the two answers had drifted: this file rejected
|
|
85
|
+
* `\\server\share` while the panel accepted it (审计 0112 P2-11). Both UNC spellings are accepted now, which is
|
|
86
|
+
* what this function always claimed in its one-line doc.
|
|
87
|
+
*/
|
|
88
|
+
export { isAbsoluteLocalPath };
|
|
81
89
|
/**
|
|
82
90
|
* Normalize a host path for comparison: separators to `/`, `.`/`..` resolved, trailing
|
|
83
91
|
* separators dropped, and (optionally) the drive letter and case folded.
|
|
84
92
|
*
|
|
93
|
+
* The **implementation** is `shared/root-keys.ts` (the client's key needs the same normalisation). What stays
|
|
94
|
+
* here is the platform default: `caseInsensitive` defaults to "this host folds case on Windows", which is a
|
|
95
|
+
* fact only the host has — a browser bundle has no `process` and must not guess it.
|
|
96
|
+
*
|
|
85
97
|
* @param path - host path in either separator spelling.
|
|
86
98
|
* @param options - `caseInsensitive` folds case for comparison keys.
|
|
87
99
|
* @returns the normalized path.
|
|
88
100
|
*/
|
|
89
|
-
export declare function normalizeLocalPath(path: string, options?:
|
|
90
|
-
readonly caseInsensitive?: boolean;
|
|
91
|
-
}): string;
|
|
101
|
+
export declare function normalizeLocalPath(path: string, options?: RootKeyOptions): string;
|
|
92
102
|
/** Whether a host path is `root` itself or a descendant of it. */
|
|
93
103
|
export declare function localPathContains(root: string, candidate: string, options?: {
|
|
94
104
|
readonly caseInsensitive?: boolean;
|
|
95
105
|
}): boolean;
|
|
96
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Stable identity of a root, used as a cache/route key.
|
|
108
|
+
*
|
|
109
|
+
* The **spelling** is `shared/root-keys.ts`'s `rootKeySpelling`: the client rebuilds this same key for a row
|
|
110
|
+
* whose answer carried none, and a second spelling is what made the panel's delete button address a root the
|
|
111
|
+
* registry did not have (审计 0024 §8.3). Only the error policy and the platform's case fold stay here.
|
|
112
|
+
*/
|
|
97
113
|
export declare function rootKey(root: RootRef): string;
|
|
98
114
|
/** The model-facing and UI-facing spelling of a root's directory. */
|
|
99
115
|
export declare function rootDisplay(root: RootRef): string;
|
|
@@ -105,4 +121,3 @@ export declare function rootsOverlap(left: RootRef, right: RootRef): boolean;
|
|
|
105
121
|
export declare function validateRoot(root: RootRef): void;
|
|
106
122
|
/** FNV-1a (32-bit) over UTF-16 code units, rendered as 8 lowercase hex characters. */
|
|
107
123
|
export declare function fnv1aHex(input: string): string;
|
|
108
|
-
//# sourceMappingURL=root.d.ts.map
|
|
@@ -148,4 +148,3 @@ export declare function ambiguousSessionRootMessage(candidates: readonly Session
|
|
|
148
148
|
* @returns whether the root may serve that caller.
|
|
149
149
|
*/
|
|
150
150
|
export declare function rootVisibleToSession(root: RootRef, cwd: string | undefined, identity?: SessionIdentity): boolean;
|
|
151
|
-
//# sourceMappingURL=session-roots.d.ts.map
|
|
@@ -334,4 +334,3 @@ export declare function serializeRecycleBinIndex(entries: readonly RecycleBinEnt
|
|
|
334
334
|
* @throws SshDevError `TRASH_NOT_FOUND` when the document cannot be read as an index.
|
|
335
335
|
*/
|
|
336
336
|
export declare function parseRecycleBinIndex(text: string): ParsedRecycleBinIndex;
|
|
337
|
-
//# sourceMappingURL=recycle-bin.d.ts.map
|
|
@@ -257,4 +257,3 @@ export declare function isTransferFailure(error: unknown, kind?: TransferFailure
|
|
|
257
257
|
*/
|
|
258
258
|
export declare function digestsMatch(left: string | undefined, right: string | undefined): boolean;
|
|
259
259
|
export { formatBytes, formatDuration };
|
|
260
|
-
//# sourceMappingURL=transfer.d.ts.map
|
|
@@ -522,6 +522,20 @@ export interface Transport {
|
|
|
522
522
|
}
|
|
523
523
|
/** Encode bytes as base64 without line wrapping. */
|
|
524
524
|
export declare function encodeBase64(bytes: Uint8Array): string;
|
|
525
|
-
/**
|
|
525
|
+
/**
|
|
526
|
+
* Decode base64, ignoring line breaks produced by remote tooling.
|
|
527
|
+
*
|
|
528
|
+
* **两次多余的整串处理被去掉了**(审计 0112 P3-2):
|
|
529
|
+
*
|
|
530
|
+
* 1. `text.replace(/\s+/g, '')` 先把整串扫一遍去掉空白。Node 的 base64 解码**本来就忽略空白**
|
|
531
|
+
* (`\n` / `\r\n` / 空格 / 制表符都已实测逐字节等价,见本函数下方的测试),所以这一遍纯属浪费:
|
|
532
|
+
* 9 MiB 负载(12.7 MB base64)实测 17.3 ms → 7.1 ms。
|
|
533
|
+
* 2. `new Uint8Array(...)` 把解码结果再拷一遍。4 KiB 以上的解码本来就不走 Buffer 的共享池,
|
|
534
|
+
* `Buffer.from(str, 'base64')` 的返回对象已经是独占、正好大小的 `Uint8Array`,直接交出去即可
|
|
535
|
+
* (9 MiB 的一次拷贝实测 1.4 ms,而它正是这条读路径上最大的一块)。
|
|
536
|
+
*
|
|
537
|
+
* **小结果仍然拷一次,这是有意的**:`Buffer.from(string)` 在 4 KiB 以下会落进 Node 的 64 KiB 共享池,
|
|
538
|
+
* 原样返回会让一个几十字节的缓存值长期钉住 64 KiB(读缓存按 `byteLength` 记账,看不见这块)。
|
|
539
|
+
* 那次拷贝是几十字节,与热路径无关。
|
|
540
|
+
*/
|
|
526
541
|
export declare function decodeBase64(text: string): Uint8Array;
|
|
527
|
-
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -53,4 +53,3 @@ export interface AgentPreflight {
|
|
|
53
53
|
* @returns the preflight, an installation lookup, and a way to forget a connection.
|
|
54
54
|
*/
|
|
55
55
|
export declare function createAgentPreflight(options: AgentPreflightOptions): AgentPreflight;
|
|
56
|
-
//# sourceMappingURL=agent-preflight.d.ts.map
|
|
@@ -139,4 +139,3 @@ export declare class RemoteFileReferenceService extends FileReferenceService {
|
|
|
139
139
|
list(agent: Agent, query: string, signal: AbortSignal): Promise<FileReferenceCandidate[]>;
|
|
140
140
|
}
|
|
141
141
|
export default RemoteFileReferenceService;
|
|
142
|
-
//# sourceMappingURL=file-reference-provider.d.ts.map
|
|
@@ -101,7 +101,6 @@ export interface RoutedFsProviderOptions {
|
|
|
101
101
|
* model's file tools follow the router (see `cordis.patch.yml`).
|
|
102
102
|
*/
|
|
103
103
|
export declare class RoutedFsProvider extends FileSystem {
|
|
104
|
-
#private;
|
|
105
104
|
static inject: string[];
|
|
106
105
|
protected readonly rangeReader: BackendRangeReader | undefined;
|
|
107
106
|
protected readonly rangeChunkBytes: number;
|
|
@@ -365,4 +364,3 @@ export declare function createBackendRangeReader(store: (backend: Backend, offse
|
|
|
365
364
|
export declare function toFsError(error: SshDevError): FsError;
|
|
366
365
|
/** Codes this provider can surface, exported for tests that assert the mapping table. */
|
|
367
366
|
export declare const MAPPED_DOMAIN_CODES: readonly SshDevErrorCode[];
|
|
368
|
-
//# sourceMappingURL=fs-provider.d.ts.map
|
|
@@ -209,4 +209,3 @@ export declare const RESUME_VERIFY_BYTES: number;
|
|
|
209
209
|
* @returns the upload/download operations; no state is kept between calls.
|
|
210
210
|
*/
|
|
211
211
|
export declare function createTransferService(dependencies: TransferDependencies): TransferService;
|
|
212
|
-
//# sourceMappingURL=transfer-service.d.ts.map
|
package/lib/types/src/index.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host plugin entry: configuration, services and the object graph behind this plugin.
|
|
3
|
+
*
|
|
4
|
+
* It provides two services and nothing else, deliberately:
|
|
5
|
+
*
|
|
6
|
+
* - `sshDevConnections` — the validated connection profiles (secrets referenced by credential key).
|
|
7
|
+
* - `sshDevRoots` — the {@link RootRegistry} the `ctx.fs` provider (`dsh-over-ssh/fs`) injects.
|
|
8
|
+
*
|
|
9
|
+
* Transports are constructed lazily and owned by a {@link TransportService}, so a client half (or a
|
|
10
|
+
* root added at runtime) simply calls into the registry and everything else follows. Nothing here
|
|
11
|
+
* reads a secret eagerly: passwords live in `ctx.credentials` and are resolved when a connection is
|
|
12
|
+
* actually opened.
|
|
13
|
+
*
|
|
14
|
+
* @module dsh-over-ssh
|
|
15
|
+
*/
|
|
1
16
|
import { Context } from '@deepseek-ai/cordis';
|
|
2
17
|
import { TransportService } from './host/app/transport/transport-service.ts';
|
|
3
18
|
import { Config } from './config.ts';
|
|
@@ -54,6 +69,14 @@ declare module '@deepseek-ai/cordis' {
|
|
|
54
69
|
sshDevSessionAdmin: SessionAdminService;
|
|
55
70
|
}
|
|
56
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Read a session log's header line.
|
|
74
|
+
*
|
|
75
|
+
* The bounded reader lives in {@link createDiskSessionHeaderReader} rather than here: a composition root
|
|
76
|
+
* cannot be exercised by a test (审计 0046 记录了同款教训), and a reader whose *memory bound* is its whole
|
|
77
|
+
* contract must have one. The previous inline version read the entire log before slicing 256 KiB off it —
|
|
78
|
+
* measured at 105.3 MiB of reads for this machine's 73 sessions, worst single log 10.9 MiB (审计 0050).
|
|
79
|
+
*/
|
|
57
80
|
/**
|
|
58
81
|
* Install the plugin.
|
|
59
82
|
*
|
|
@@ -63,4 +86,3 @@ declare module '@deepseek-ai/cordis' {
|
|
|
63
86
|
*/
|
|
64
87
|
export { Config };
|
|
65
88
|
export declare function apply(ctx: Context, config: ResolvedConfig): void;
|
|
66
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 根路径与根键的**唯一拼写规则**:client 与 host 两侧都 import 这一份。
|
|
3
|
+
*
|
|
4
|
+
* 为什么在 `shared/`:这三条规则此前各有两份实现,而每一对都已经分叉过一次(审计 0112 P2-11):
|
|
5
|
+
*
|
|
6
|
+
* - **根键**:客户端拼 `local:<原样路径>`,宿主拼 `local:<规范化路径>`(Windows 上还折叠大小写)。
|
|
7
|
+
* 0024 §8.3 的"删除按钮发出宿主匹配不上的键"就是这个分叉的直接后果——面板把那行显示出来,
|
|
8
|
+
* 点删除却什么也没发生,而两边各自的用例都是绿的;
|
|
9
|
+
* - **绝对本地路径**:宿主不认 `\\server\share`(它先规范化再判断,所以只认 `//server/share`),
|
|
10
|
+
* 客户端认。同一个 UNC 路径在两半得到相反的答案;
|
|
11
|
+
* - **远端父目录**:客户端自己 `lastIndexOf('/')`,宿主的 `remoteDirname` 先规范化(`/a//b/` 与
|
|
12
|
+
* `/a/b` 因此是不同的答案)。
|
|
13
|
+
*
|
|
14
|
+
* `shared/` 是两侧唯一都能 import 的位置:`tests/architecture.test.ts` 规定 client 只能依赖
|
|
15
|
+
* `client` 与 `shared`,而 `shared` 只能依赖自己。这也是 `routes.ts` / `format.ts` 住在这里的理由。
|
|
16
|
+
*
|
|
17
|
+
* 本模块是**纯函数**,且**不读 `process`**:它会被打进浏览器 bundle(`platform: 'browser'`),
|
|
18
|
+
* 那里没有 `process`。平台相关的决定由调用方作为参数传进来——见 {@link rootKeySpelling} 的
|
|
19
|
+
* `caseInsensitive`:宿主的 `domain/roots/root.ts` 传 `process.platform === 'win32'`,客户端不猜。
|
|
20
|
+
*
|
|
21
|
+
* 三个函数都是**全函数**(不抛错):宿主那一侧的错误策略(`SshDevError('ROOT_INVALID')`)留在
|
|
22
|
+
* `domain/` 里,因为客户端在 reducer 里抛错等于把界面炸掉。所以这里能共享的是**规则**,不是
|
|
23
|
+
* "遇到坏输入怎么办"。
|
|
24
|
+
*
|
|
25
|
+
* @module dsh-over-ssh/shared/root-keys
|
|
26
|
+
*/
|
|
27
|
+
/** Where a root lives: on this machine, or behind a connection. */
|
|
28
|
+
export type RootLocation = 'local' | 'remote';
|
|
29
|
+
/**
|
|
30
|
+
* One option bag for every spelling rule here.
|
|
31
|
+
*
|
|
32
|
+
* Only `caseInsensitive` exists today, and only for **local** paths: a Windows host folds case in the
|
|
33
|
+
* registry, a POSIX host does not, and a browser cannot know which. So the decision travels as an argument
|
|
34
|
+
* instead of being read from `process` inside a function that both halves call.
|
|
35
|
+
*/
|
|
36
|
+
export interface RootKeyOptions {
|
|
37
|
+
/** Fold case in a local path/key. Defaults to `false` — "keep the caller's case". */
|
|
38
|
+
readonly caseInsensitive?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether a host path is absolute in either the Windows or the POSIX spelling.
|
|
42
|
+
*
|
|
43
|
+
* Both UNC spellings are accepted: `\\server\share` (what a Windows operator types) and `//server/share`
|
|
44
|
+
* (what {@link normalizeLocalPath} produces). The host used to accept only the second, the client only the
|
|
45
|
+
* first — so the panel and `makeLocalRoot` disagreed about the same string.
|
|
46
|
+
*
|
|
47
|
+
* @param path - candidate host path.
|
|
48
|
+
* @returns whether it names an absolute host path.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isAbsoluteLocalPath(path: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Normalize a host path for comparison: separators to `/`, `.`/`..` resolved, trailing separators dropped,
|
|
53
|
+
* and (optionally) the drive letter and case folded.
|
|
54
|
+
*
|
|
55
|
+
* Total: a relative spelling comes back as a relative spelling (`src` → `src`). The caller decides whether
|
|
56
|
+
* that is an error (the host's `makeLocalRoot`/`validateRoot` check {@link isAbsoluteLocalPath} after this).
|
|
57
|
+
*
|
|
58
|
+
* @param path - host path in either separator spelling.
|
|
59
|
+
* @param options - `caseInsensitive` folds case for comparison keys.
|
|
60
|
+
* @returns the normalized path.
|
|
61
|
+
*/
|
|
62
|
+
export declare function normalizeLocalPath(path: string, options?: RootKeyOptions): string;
|
|
63
|
+
/**
|
|
64
|
+
* Normalize an absolute POSIX path: repeated separators collapsed, `.`/`..` resolved, trailing separators
|
|
65
|
+
* dropped (except for the root).
|
|
66
|
+
*
|
|
67
|
+
* Total: `undefined` means "not an absolute POSIX spelling". The host's `normalizeRemotePath` is the same
|
|
68
|
+
* rule plus the `SshDevError('ROOT_INVALID')` policy on top.
|
|
69
|
+
*
|
|
70
|
+
* @param path - candidate absolute POSIX path.
|
|
71
|
+
* @returns the normalized path, or `undefined` when the spelling is not absolute.
|
|
72
|
+
*/
|
|
73
|
+
export declare function normalizePosixPath(path: string): string | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* The parent directory of a **normalized** absolute POSIX path; the root's parent is `/`.
|
|
76
|
+
*
|
|
77
|
+
* One rule, two policies on top: the host's `remoteDirname` answers `/` for the root (a root's parent is
|
|
78
|
+
* itself, which is what its callers assume), while the directory browser's `parentRemotePath` answers
|
|
79
|
+
* `undefined` there (the "up" button must be disabled). The separator arithmetic is not repeated.
|
|
80
|
+
*
|
|
81
|
+
* @param normalized - an absolute POSIX path already passed through {@link normalizePosixPath}.
|
|
82
|
+
* @returns the parent directory.
|
|
83
|
+
*/
|
|
84
|
+
export declare function posixDirname(normalized: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* The key one root answers to, spelled the way **both halves** must spell it:
|
|
87
|
+
* `local:<normalized local path>` or `remote:<connectionId>:<normalized POSIX path>`.
|
|
88
|
+
*
|
|
89
|
+
* This is the string a client sends back to remove a root and the string the registry stores, so the two
|
|
90
|
+
* have to be the same function — the earlier client spelling (`local:-:<path>`, then `local:<raw path>`)
|
|
91
|
+
* produced keys the host could not match (audit 0024 §8.3, §8.5).
|
|
92
|
+
*
|
|
93
|
+
* Case is **not** folded here unless the caller asks: the host passes `{ caseInsensitive: process.platform
|
|
94
|
+
* === 'win32' }` (that is where its registry folds), and the client passes nothing because it cannot know
|
|
95
|
+
* the host's platform. Case-differing keys are therefore matched by {@link rootKeyIdentity} (the client's
|
|
96
|
+
* join) and by the host's own `sameRootKey`/`liveKeyFor` comparison — never by string equality on the key.
|
|
97
|
+
*
|
|
98
|
+
* @param location - local or remote.
|
|
99
|
+
* @param path - host path (either separator spelling) or absolute POSIX path.
|
|
100
|
+
* @param connectionId - the connection for a remote root; absent spells `remote::<path>` (the client's
|
|
101
|
+
* fallback for a malformed answer — the host rejects such a root before it ever gets here).
|
|
102
|
+
* @param options - `caseInsensitive` folds case in a local key.
|
|
103
|
+
* @returns the key.
|
|
104
|
+
*/
|
|
105
|
+
export declare function rootKeySpelling(location: RootLocation, path: string, connectionId?: string, options?: RootKeyOptions): string;
|
|
106
|
+
/**
|
|
107
|
+
* The identity two root keys are joined by: `local:` keys compare **case-insensitively**, remote keys do not.
|
|
108
|
+
*
|
|
109
|
+
* Why unconditional for local: the host's registry folds a Windows local path to lower case while the panel's
|
|
110
|
+
* own file keeps the caller's case, so "the same root" routinely arrives with two spellings. The host has
|
|
111
|
+
* always compared this way (`sameRootKey` in `app/roots/user-roots.ts`, out of this change's write scope);
|
|
112
|
+
* this is the client's half of the same rule, and without it a live root reads as "not in the file", which
|
|
113
|
+
* silently removes its delete button (audit 0024 §8.5).
|
|
114
|
+
*
|
|
115
|
+
* Remote paths are POSIX and therefore case-sensitive, so their keys are compared verbatim.
|
|
116
|
+
*
|
|
117
|
+
* @param key - one root key (or anything shaped like one).
|
|
118
|
+
* @returns the join identity.
|
|
119
|
+
*/
|
|
120
|
+
export declare function rootKeyIdentity(key: string): string;
|
|
@@ -141,4 +141,3 @@ export interface CredentialsLike {
|
|
|
141
141
|
}
|
|
142
142
|
/** 会话日志头读取器(原先在 index.ts 底部,被 tools 段的会话管理使用)。 */
|
|
143
143
|
export declare const readSessionHeader: (dir: string) => Promise<import("../host/app/session-admin/session-admin-contract.ts").SessionHeader | undefined>;
|
|
144
|
-
//# sourceMappingURL=helpers.d.ts.map
|