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,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Which terminal a session gets: the remote host, or the local machine.
|
|
3
|
-
*
|
|
4
|
-
* The platform's only official extension point for the Web terminal is `terminalController.Config.shell`
|
|
5
|
-
* (`{ path, name, args }`), so this plugin ships a **wrapper** as that shell: the wrapper decides at launch
|
|
6
|
-
* time whether to `exec ssh` or the local login shell. See `doc/02-platform/terminal.md` §5 for the evidence
|
|
7
|
-
* and the accepted costs.
|
|
8
|
-
*
|
|
9
|
-
* This module is the decision itself, kept pure (no filesystem, no spawn) so it can be tested in
|
|
10
|
-
* milliseconds — the wrapper script is a thin `spawn` around it.
|
|
11
|
-
*
|
|
12
|
-
* Two inputs decide it, in this order:
|
|
13
|
-
*
|
|
14
|
-
* 1. **the session's recorded target** (`state/<sessionId>.json`): the host writes it when it resolves a
|
|
15
|
-
* remote root for that session, so it works even when the core hands us an unrelated cwd;
|
|
16
|
-
* 2. **the root manifest** (`roots.json`): a directory→connection map, used when the wrapper has no session
|
|
17
|
-
* id (a terminal opened by hand) — a cwd under a remote root's anchor means the user is working remotely.
|
|
18
|
-
*
|
|
19
|
-
* @module dsh-remote-workspace/domain/terminal-target
|
|
20
|
-
*/
|
|
21
|
-
/** How the wrapper reaches a connection's host: pre-built ssh arguments the host already resolved. */
|
|
22
|
-
export interface SshInvocation {
|
|
23
|
-
/** `user@host` or a `~/.ssh/config` alias. */
|
|
24
|
-
readonly destination: string;
|
|
25
|
-
/** Extra arguments (`-i`, `-o UserKnownHostsFile=…`, `-p`, jump options…), already credential-resolved. */
|
|
26
|
-
readonly args: readonly string[];
|
|
27
|
-
}
|
|
28
|
-
/** One remote root as the wrapper needs it. */
|
|
29
|
-
export interface ManifestRoot {
|
|
30
|
-
readonly connectionId: string;
|
|
31
|
-
/** Backend-absolute remote path (POSIX). */
|
|
32
|
-
readonly remoteRoot: string;
|
|
33
|
-
/** Local anchor directory that maps to this remote root. */
|
|
34
|
-
readonly anchorPath: string;
|
|
35
|
-
/** How to reach the host. */
|
|
36
|
-
readonly ssh: SshInvocation;
|
|
37
|
-
}
|
|
38
|
-
/** The root manifest the host writes for the wrapper. */
|
|
39
|
-
export interface RootManifest {
|
|
40
|
-
/** Manifest format version; a wrapper that does not know the version falls back to local. */
|
|
41
|
-
readonly version: number;
|
|
42
|
-
readonly roots: readonly ManifestRoot[];
|
|
43
|
-
}
|
|
44
|
-
/** One session's recorded remote target. */
|
|
45
|
-
export interface SessionState {
|
|
46
|
-
readonly sessionId: string;
|
|
47
|
-
readonly connectionId: string;
|
|
48
|
-
readonly remoteRoot: string;
|
|
49
|
-
readonly ssh: SshInvocation;
|
|
50
|
-
/** Epoch milliseconds; the wrapper ignores entries older than {@link SESSION_STATE_MAX_AGE_MS}. */
|
|
51
|
-
readonly recordedAt: number;
|
|
52
|
-
}
|
|
53
|
-
/** Current manifest version. */
|
|
54
|
-
export declare const MANIFEST_VERSION = 1;
|
|
55
|
-
/** A session state older than this is ignored (a stale file must not send the user to the wrong host). */
|
|
56
|
-
export declare const SESSION_STATE_MAX_AGE_MS: number;
|
|
57
|
-
/** The decision the wrapper acts on. */
|
|
58
|
-
export type TerminalDecision = {
|
|
59
|
-
readonly kind: 'remote';
|
|
60
|
-
readonly connectionId: string;
|
|
61
|
-
readonly remoteRoot: string;
|
|
62
|
-
/** Full argv to spawn: `[ssh, -tt, …args, destination, --, command]`. */
|
|
63
|
-
readonly argv: readonly string[];
|
|
64
|
-
/** Remote command: `cd <root> && exec <login shell> -l`. */
|
|
65
|
-
readonly remoteCommand: string;
|
|
66
|
-
/** Why this decision was taken (for diagnostics and tests). */
|
|
67
|
-
readonly reason: 'session' | 'anchor';
|
|
68
|
-
} | {
|
|
69
|
-
readonly kind: 'local';
|
|
70
|
-
/** Full argv to spawn: the local login shell. */
|
|
71
|
-
readonly argv: readonly string[];
|
|
72
|
-
readonly reason: 'no-target' | 'state-unusable' | 'manifest-unusable';
|
|
73
|
-
};
|
|
74
|
-
/** Options for {@link decideTerminal}. */
|
|
75
|
-
export interface DecideTerminalOptions {
|
|
76
|
-
/** Working directory the terminal was launched in. */
|
|
77
|
-
readonly cwd: string;
|
|
78
|
-
/** Manifest, when readable and valid. */
|
|
79
|
-
readonly manifest?: RootManifest;
|
|
80
|
-
/** This session's state, when readable and valid. */
|
|
81
|
-
readonly sessionState?: SessionState;
|
|
82
|
-
/** Local login shell to fall back to (platform default resolved by the caller). */
|
|
83
|
-
readonly localShell: string;
|
|
84
|
-
/** Remote login shell; `$SHELL` expands remotely, which is the right default. */
|
|
85
|
-
readonly remoteShell?: string;
|
|
86
|
-
/** Clock, injected for the staleness check. */
|
|
87
|
-
readonly now?: number;
|
|
88
|
-
}
|
|
89
|
-
/** Quote one word for a POSIX shell (single quotes). */
|
|
90
|
-
export declare function posixQuote(value: string): string;
|
|
91
|
-
/** Whether a path is the anchor itself or lives under it. */
|
|
92
|
-
export declare function isUnder(candidate: string, directory: string): boolean;
|
|
93
|
-
/**
|
|
94
|
-
* Parse a root manifest.
|
|
95
|
-
*
|
|
96
|
-
* @param raw - file contents.
|
|
97
|
-
* @returns the manifest, or `undefined` when it is unusable (wrong version, malformed, empty).
|
|
98
|
-
*/
|
|
99
|
-
export declare function parseRootManifest(raw: string): RootManifest | undefined;
|
|
100
|
-
/**
|
|
101
|
-
* Parse one session state file.
|
|
102
|
-
*
|
|
103
|
-
* @param raw - file contents.
|
|
104
|
-
* @returns the state, or `undefined` when malformed.
|
|
105
|
-
*/
|
|
106
|
-
export declare function parseSessionState(raw: string): SessionState | undefined;
|
|
107
|
-
/** Serialize a manifest for the wrapper (stable key order, so the file diff is readable). */
|
|
108
|
-
export declare function serializeRootManifest(manifest: RootManifest): string;
|
|
109
|
-
/** Serialize one session state. */
|
|
110
|
-
export declare function serializeSessionState(state: SessionState): string;
|
|
111
|
-
/** Build the command the remote shell runs: enter the workspace and be a login shell. */
|
|
112
|
-
export declare function remoteCommandFor(remoteRoot: string, remoteShell?: string): string;
|
|
113
|
-
/**
|
|
114
|
-
* Build the ssh argv for one remote target.
|
|
115
|
-
*
|
|
116
|
-
* `-tt` is what makes an interactive terminal work through the wrapper (the child needs a TTY on both
|
|
117
|
-
* sides). `--` ends option parsing before the destination, and the remote command is a single argument.
|
|
118
|
-
*
|
|
119
|
-
* @param ssh - resolved destination and credential arguments.
|
|
120
|
-
* @param remoteCommand - command to run remotely.
|
|
121
|
-
* @returns the argv to spawn.
|
|
122
|
-
*/
|
|
123
|
-
export declare function sshArgvFor(ssh: SshInvocation, remoteCommand: string): readonly string[];
|
|
124
|
-
/**
|
|
125
|
-
* Decide which terminal to open.
|
|
126
|
-
*
|
|
127
|
-
* @param options - cwd, manifest, session state, local shell, clock.
|
|
128
|
-
* @returns the decision, always total (never throws): an unusable input degrades to the local shell, with
|
|
129
|
-
* `reason` naming why.
|
|
130
|
-
*/
|
|
131
|
-
export declare function decideTerminal(options: DecideTerminalOptions): TerminalDecision;
|
|
132
|
-
//# sourceMappingURL=terminal-target.d.ts.map
|
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure request/response logic for the remote tools.
|
|
3
|
-
*
|
|
4
|
-
* Kept in the domain layer on purpose (AGENTS.md 红线 2): no `@deepseek-ai/*` import, so command building,
|
|
5
|
-
* argument clamping and output parsing are all testable offline, in milliseconds, with no transport.
|
|
6
|
-
*
|
|
7
|
-
* Everything here is **bounded**: a tool call is model-driven, so an unbounded `grep` or `exec` would let a
|
|
8
|
-
* single call read an entire remote disk. Caps are part of the contract, and hitting one is *reported*
|
|
9
|
-
* (`truncated`) rather than silently obeyed.
|
|
10
|
-
*
|
|
11
|
-
* **One path rule for the whole tool family** (audit 0052): {@link resolveUnderRoot} is the only place that
|
|
12
|
-
* turns a model-supplied spelling into a remote path. Both spellings are accepted — an absolute path must be
|
|
13
|
-
* inside the root (an outside one is *refused*, never silently re-rooted) and a relative path is resolved
|
|
14
|
-
* against the root, where `..` folds but cannot climb out. `joinUnderRoot` is the legacy folder kept for the
|
|
15
|
-
* transfer layer; it is now idempotent for in-root absolute paths so a resolved path cannot be prefixed twice
|
|
16
|
-
* (that doubling was the cause of `remote_exec { cwd: "<the root itself>/..." }` failing).
|
|
17
|
-
*
|
|
18
|
-
* @module dsh-over-ssh/domain/tool-requests
|
|
19
|
-
*/
|
|
20
|
-
import { quote } from './shell.ts';
|
|
21
|
-
/** Cap on matches returned by one search. */
|
|
22
|
-
export declare const MAX_GREP_RESULTS = 200;
|
|
23
|
-
/** Cap on paths returned by one glob. */
|
|
24
|
-
export declare const MAX_GLOB_RESULTS = 500;
|
|
25
|
-
/** Cap on bytes of one command's output handed back to the model. */
|
|
26
|
-
export declare const MAX_OUTPUT_BYTES: number;
|
|
27
|
-
/** Default cooperative timeout for a remote command. */
|
|
28
|
-
export declare const DEFAULT_EXEC_TIMEOUT_MS = 30000;
|
|
29
|
-
/** Hard ceiling for a model-requested command timeout. */
|
|
30
|
-
export declare const MAX_EXEC_TIMEOUT_MS = 300000;
|
|
31
|
-
/**
|
|
32
|
-
* Cap on environment entries one command may carry.
|
|
33
|
-
*
|
|
34
|
-
* A bound rather than a silent trim: the whole point of `env` is that the caller can see what it asked
|
|
35
|
-
* for, so an oversized map is refused by name instead of having entries quietly dropped.
|
|
36
|
-
*/
|
|
37
|
-
export declare const MAX_EXEC_ENV_ENTRIES = 64;
|
|
38
|
-
/** A search request, after validation. */
|
|
39
|
-
export interface GrepRequest {
|
|
40
|
-
/** Pattern text (literal or regular expression). */
|
|
41
|
-
readonly pattern: string;
|
|
42
|
-
/** Directory to search; a root-relative or in-root absolute spelling, `undefined` means the root itself. */
|
|
43
|
-
readonly path: string | undefined;
|
|
44
|
-
/** Whether `pattern` is a regular expression. */
|
|
45
|
-
readonly regex: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Whether matching distinguishes case. Default `false`, matching the agent's wire default
|
|
48
|
-
* (`caseSensitive: false`) — the two tiers must not disagree about one tool call.
|
|
49
|
-
*/
|
|
50
|
-
readonly caseSensitive?: boolean | undefined;
|
|
51
|
-
/**
|
|
52
|
-
* Whether ignore rules are dropped: VCS ignores (`.gitignore`) **and** {@link DEFAULT_EXCLUDE_DIRS}.
|
|
53
|
-
* Default `false`.
|
|
54
|
-
*
|
|
55
|
-
* The tiers can only do part of this, and the split is deliberate rather than silent: Tier 2 (the agent)
|
|
56
|
-
* stops applying both, while Tier 1's `grep` never read `.gitignore` at all, so there the flag controls
|
|
57
|
-
* only the noise-directory list. `tests/remote-tool-backend.test.ts` pins that both tiers receive the same
|
|
58
|
-
* intent, and the residual difference is stated in `remote_grep`'s description.
|
|
59
|
-
*/
|
|
60
|
-
readonly noIgnore?: boolean | undefined;
|
|
61
|
-
/** Filename filters, symmetric with the agent's `search.grep` `exclude`. */
|
|
62
|
-
readonly include?: readonly string[] | undefined;
|
|
63
|
-
readonly maxResults: number;
|
|
64
|
-
}
|
|
65
|
-
/** A glob request, after validation. */
|
|
66
|
-
export interface GlobRequest {
|
|
67
|
-
/** Substring or suffix to match against enumerated paths. */
|
|
68
|
-
readonly pattern: string;
|
|
69
|
-
/** Directory to enumerate; a root-relative or in-root absolute spelling, `undefined` means the root itself. */
|
|
70
|
-
readonly path: string | undefined;
|
|
71
|
-
readonly maxResults: number;
|
|
72
|
-
}
|
|
73
|
-
/** A command request, after validation. */
|
|
74
|
-
export interface ExecRequest {
|
|
75
|
-
readonly command: string;
|
|
76
|
-
/** Working directory; a root-relative or in-root absolute spelling, `undefined` means the root itself. */
|
|
77
|
-
readonly cwd: string | undefined;
|
|
78
|
-
/** Environment assignments applied to this command only; `undefined` when none were requested. */
|
|
79
|
-
readonly env?: Readonly<Record<string, string>> | undefined;
|
|
80
|
-
readonly timeoutMs: number;
|
|
81
|
-
}
|
|
82
|
-
/** One search hit. */
|
|
83
|
-
export interface GrepHit {
|
|
84
|
-
readonly path: string;
|
|
85
|
-
/** 1-based line number. */
|
|
86
|
-
readonly line: number;
|
|
87
|
-
readonly text: string;
|
|
88
|
-
}
|
|
89
|
-
/** Search outcome; `truncated` is set when a cap was hit. */
|
|
90
|
-
export interface GrepOutcome {
|
|
91
|
-
readonly matches: readonly GrepHit[];
|
|
92
|
-
readonly truncated: boolean;
|
|
93
|
-
/** Which tier answered (`agent` or the shell strategy). */
|
|
94
|
-
readonly strategy: string;
|
|
95
|
-
/** Why the search stopped early, when the answering tier can say (audit 0052 P7). */
|
|
96
|
-
readonly truncation?: SearchTruncation | undefined;
|
|
97
|
-
}
|
|
98
|
-
/** Text plus the fact that something was cut. */
|
|
99
|
-
export interface BoundedText {
|
|
100
|
-
readonly text: string;
|
|
101
|
-
readonly truncated: boolean;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Normalize a caller-supplied permission spelling into the octal digit string `chmod` takes.
|
|
105
|
-
*
|
|
106
|
-
* A number is read as **octal digits**, because that is what a caller who writes `755` means; a string may
|
|
107
|
-
* also carry the `0o` prefix. Everything else — `"rwxr-xr-x"`, `"8"`, `true`, `""` — is refused rather than
|
|
108
|
-
* guessed: quietly ignoring a requested mode is precisely the class of failure this round removes, and a
|
|
109
|
-
* wrong-but-accepted mode on a build script is worse than a refusal.
|
|
110
|
-
*
|
|
111
|
-
* @param value - the raw `mode` argument.
|
|
112
|
-
* @returns the normalized 3-4 digit octal string, or an error naming the accepted forms.
|
|
113
|
-
*/
|
|
114
|
-
export declare function fileModeArg(value: unknown): {
|
|
115
|
-
readonly mode: string | undefined;
|
|
116
|
-
} | {
|
|
117
|
-
readonly error: string;
|
|
118
|
-
};
|
|
119
|
-
/**
|
|
120
|
-
* Cap on filename filters one search may carry.
|
|
121
|
-
*
|
|
122
|
-
* Bounded for the same reason every other cap here is: the filters become `--include` argv words in the
|
|
123
|
-
* shell strategy, so an unbounded list is an unbounded command line.
|
|
124
|
-
*/
|
|
125
|
-
export declare const MAX_GREP_INCLUDES = 16;
|
|
126
|
-
/**
|
|
127
|
-
* The noise directory names a search excludes by default.
|
|
128
|
-
*
|
|
129
|
-
* **This mirrors `dsh-over-ssh-agent/internal/index/scan.go`'s `DefaultExcludes`.** The duplication is forced:
|
|
130
|
-
* Tier 1 is a plain `grep` with no agent to ask, so it has to name the same directories itself, or the same
|
|
131
|
-
* tool call would search a different file set depending on which tier answered — the disagreement this
|
|
132
|
-
* module already refuses to allow for case sensitivity.
|
|
133
|
-
*
|
|
134
|
-
* Two consequences are deliberate:
|
|
135
|
-
* - the list is pinned **verbatim by a test**, so editing it is always an explicit act rather than drift;
|
|
136
|
-
* - keeping the two copies equal is a cross-repository obligation that no test in this repository can
|
|
137
|
-
* mechanically enforce. Audit 0064 records the debt, with the Go side as the source of truth.
|
|
138
|
-
*/
|
|
139
|
-
export declare const DEFAULT_EXCLUDE_DIRS: readonly string[];
|
|
140
|
-
/** Merge a requested sub-path with the root, refusing to escape it. */
|
|
141
|
-
export declare function joinUnderRoot(root: string, path: string | undefined): string;
|
|
142
|
-
/**
|
|
143
|
-
* Resolve a model-supplied path spelling into one remote path inside `root`.
|
|
144
|
-
*
|
|
145
|
-
* **One rule for the whole tool family** (`remote_exec.cwd`, `remote_grep.path`, `remote_glob.path`,
|
|
146
|
-
* `remote_delete.path`, and the file tools built on top): both spellings are accepted, and the two differ
|
|
147
|
-
* only in what an out-of-root request means.
|
|
148
|
-
*
|
|
149
|
-
* - **Absolute** (`/…`): normalized, then required to be `root` itself or below it. An outside path is
|
|
150
|
-
* **refused** with a message naming both the path and the root. It is never silently re-rooted — that
|
|
151
|
-
* silent re-rooting is what turned `cwd: "/tmp"` into `<root>/tmp` and made the remote `chdir` fail with
|
|
152
|
-
* a message about `/bin/sh` (audit 0052 P1), and it is what doubled a fully-qualified in-root path.
|
|
153
|
-
* - **Relative**: folded onto `cwd` (itself resolved by this same function) or onto `root`, with `.`
|
|
154
|
-
* dropped and `..` popping. `..` **cannot climb out of the root**: extra leading `..` are ignored, which
|
|
155
|
-
* is the pre-existing, deliberately-kept clamp behaviour (audit 0052 P1.3). It also cannot climb above
|
|
156
|
-
* `root` from a `cwd`, so `cwd: "src", path: "../../etc"` still lands in `<root>/etc`.
|
|
157
|
-
*
|
|
158
|
-
* A path that is empty/blank means the root itself. `cwd` is ignored for an absolute `path`.
|
|
159
|
-
*
|
|
160
|
-
* An `ssh://<connection>/<absolute>` spelling is accepted **when it names the connection this call runs
|
|
161
|
-
* on** (`connectionId`). Its own refusal message used to recommend that spelling while the parser did not
|
|
162
|
-
* understand it, so a caller who followed the advice got `E_NOT_FOUND` (audit 0064 P2). A reference to a
|
|
163
|
-
* *different* connection is refused by name: these tools are bound to one remote root, and silently
|
|
164
|
-
* re-rooting into another host's tree is exactly the kind of guess this module refuses to make.
|
|
165
|
-
*
|
|
166
|
-
* @param root - absolute remote root directory.
|
|
167
|
-
* @param path - requested spelling, absolute, root-relative, or `ssh://`-qualified.
|
|
168
|
-
* @param cwd - optional root-relative directory the relative spelling is resolved against.
|
|
169
|
-
* @param connectionId - the connection this call targets; required to accept an `ssh://` spelling.
|
|
170
|
-
* @returns the resolved root-absolute path, or an object whose `error` explains the refusal.
|
|
171
|
-
*/
|
|
172
|
-
export declare function resolveUnderRoot(root: string, path: string, cwd?: string, connectionId?: string): string | {
|
|
173
|
-
readonly error: string;
|
|
174
|
-
};
|
|
175
|
-
/**
|
|
176
|
-
* Validate search arguments.
|
|
177
|
-
*
|
|
178
|
-
* @param args - model arguments, however malformed.
|
|
179
|
-
* @returns the request, or an error message naming the offending field.
|
|
180
|
-
*/
|
|
181
|
-
export declare function parseGrepArgs(args: unknown): GrepRequest | {
|
|
182
|
-
readonly error: string;
|
|
183
|
-
};
|
|
184
|
-
/** Validate glob arguments (same shape as search minus `regex`). */
|
|
185
|
-
export declare function parseGlobArgs(args: unknown): GlobRequest | {
|
|
186
|
-
readonly error: string;
|
|
187
|
-
};
|
|
188
|
-
/** Validate command arguments. */
|
|
189
|
-
export declare function parseExecArgs(args: unknown): ExecRequest | {
|
|
190
|
-
readonly error: string;
|
|
191
|
-
};
|
|
192
|
-
/** Whether a parse result is an error. */
|
|
193
|
-
export declare function isToolArgError(value: {
|
|
194
|
-
readonly error: string;
|
|
195
|
-
} | object): value is {
|
|
196
|
-
readonly error: string;
|
|
197
|
-
};
|
|
198
|
-
/**
|
|
199
|
-
* Quote one shell word safely (single quotes, POSIX).
|
|
200
|
-
*
|
|
201
|
-
* Re-exported from {@link ./shell.ts} rather than implemented here: this file builds `grep` command lines,
|
|
202
|
-
* and the same quoting is needed by the ssh transports and the terminal wrapper. There used to be three
|
|
203
|
-
* copies and only one of them refused NUL.
|
|
204
|
-
*/
|
|
205
|
-
export { quote };
|
|
206
|
-
/**
|
|
207
|
-
* Tier 1 search command: one bounded `grep -rn` (no ripgrep on the benchmark host).
|
|
208
|
-
*
|
|
209
|
-
* `-I` skips binaries, `-n` gives line numbers, `-E`/`-F` switch regex/literal. `-i` used to be
|
|
210
|
-
* unconditional for the reason recorded here — the agent's `search.grep` was case-insensitive by default,
|
|
211
|
-
* and the two tiers must not disagree about what the same tool call means (the real-host run caught exactly
|
|
212
|
-
* that disagreement). It is now conditional on `caseSensitive`, which the agent also honours, so the
|
|
213
|
-
* agreement is kept while the caller can finally ask for an exact match.
|
|
214
|
-
* `head` bounds the output before it crosses the wire, and `--` ends option parsing so a pattern starting
|
|
215
|
-
* with `-` is not read as a flag.
|
|
216
|
-
*
|
|
217
|
-
* `include` entries become `--include=<glob>` filters. They are **filename globs** (`*.cpp`), matching the
|
|
218
|
-
* agent's field of the same name; each entry is shell-quoted because it is model-supplied text, and the
|
|
219
|
-
* `--include=` prefix keeps a pattern that starts with `-` from being read as a flag.
|
|
220
|
-
*
|
|
221
|
-
* `noIgnore` controls {@link DEFAULT_EXCLUDE_DIRS}, emitted as `--exclude-dir=` words. **It cannot turn VCS
|
|
222
|
-
* ignores off or on**: plain `grep` never read `.gitignore`, so this tier already searches ignored files.
|
|
223
|
-
* That residual difference is stated in `remote_grep`'s description and pinned by the two-tier consistency
|
|
224
|
-
* test rather than left for a caller to discover by comparing two hosts.
|
|
225
|
-
*/
|
|
226
|
-
export declare function grepCommand(request: GrepRequest, root: string): string;
|
|
227
|
-
/**
|
|
228
|
-
* Parse `grep -rn` output (`path:line:text`).
|
|
229
|
-
*
|
|
230
|
-
* A path containing `:` is ambiguous — the first two colon-separated fields win when the second is numeric,
|
|
231
|
-
* and the rest is text. That is the same convention every editor uses, and it degrades to "line 0" rather
|
|
232
|
-
* than dropping the hit.
|
|
233
|
-
*
|
|
234
|
-
* @param stdout - command output.
|
|
235
|
-
* @param maxResults - the cap the command was built with.
|
|
236
|
-
* @returns hits plus whether the cap was reached.
|
|
237
|
-
*/
|
|
238
|
-
export declare function parseGrepOutput(stdout: string, maxResults: number): {
|
|
239
|
-
readonly matches: GrepHit[];
|
|
240
|
-
readonly truncated: boolean;
|
|
241
|
-
};
|
|
242
|
-
/**
|
|
243
|
-
* Bound one output string by bytes, cutting on a line boundary when possible.
|
|
244
|
-
*
|
|
245
|
-
* **Which end to keep is a real decision, not a default** (审计 0052 §8.1). `tail` exists because the
|
|
246
|
-
* transports already made that decision and the renderer was contradicting them: `ssh2-transport.ts` keeps
|
|
247
|
-
* the **last** 256 KiB of stderr precisely because "every consumer of this string wants the last thing the
|
|
248
|
-
* command said", and a command's verdict — the compiler error, the failing test, the `DSH_ERROR=` refusal —
|
|
249
|
-
* is at the end. Bounding to the **head** at 64 KiB then threw away the very bytes the transport had
|
|
250
|
-
* deliberately preserved, which is the user's original complaint ("编译报错永远在最后几行,恰好被砍掉")
|
|
251
|
-
* reappearing one layer up.
|
|
252
|
-
*
|
|
253
|
-
* @param text - raw output.
|
|
254
|
-
* @param maxBytes - cap.
|
|
255
|
-
* @param keep - which end survives; defaults to `head` for callers that want the beginning.
|
|
256
|
-
* @returns the kept text plus whether anything was dropped.
|
|
257
|
-
*/
|
|
258
|
-
export declare function boundOutput(text: string, maxBytes?: number, keep?: 'head' | 'tail'): BoundedText;
|
|
259
|
-
/**
|
|
260
|
-
* Make one enumerated path relative to the directory that was enumerated.
|
|
261
|
-
*
|
|
262
|
-
* The two enumerators disagree on shape: the Tier 2 agent answers paths relative to the root it was given,
|
|
263
|
-
* while the Tier 1 `find` fallback prints absolute ones. A glob pattern is anchored at the enumerated
|
|
264
|
-
* directory, so both have to arrive in the same shape before matching — and the tool's own output then has
|
|
265
|
-
* one shape too, instead of depending on which tier answered.
|
|
266
|
-
*
|
|
267
|
-
* @param base - absolute path of the enumerated directory.
|
|
268
|
-
* @param path - one path as the enumerator reported it.
|
|
269
|
-
* @returns the root-relative path, unchanged when it was already relative.
|
|
270
|
-
*/
|
|
271
|
-
export declare function relativeToRoot(base: string, path: string): string;
|
|
272
|
-
/**
|
|
273
|
-
* Rank enumerated paths for a glob query: glob match, shallowest first.
|
|
274
|
-
*
|
|
275
|
-
* The matching itself lives in `./glob-pattern.ts`, whose rules are ported from the Tier 2 agent's Go
|
|
276
|
-
* implementation. It used to be a literal substring test here, which meant the same `remote_glob` call matched
|
|
277
|
-
* different files depending on the transport (audit 0052 P3 chose substring; audit 0030 added the Go fast path
|
|
278
|
-
* and the two silently diverged).
|
|
279
|
-
*
|
|
280
|
-
* @param paths - enumerated paths, relative to the enumerated root.
|
|
281
|
-
* @param pattern - glob pattern (see `./glob-pattern.ts`); the empty pattern keeps its documented meaning of
|
|
282
|
-
* "no filter, shallowest first" rather than being compiled into a pattern that matches nothing.
|
|
283
|
-
* @param maxResults - cap.
|
|
284
|
-
* @returns matched paths plus whether the cap was reached.
|
|
285
|
-
* @throws GlobPatternError when the pattern is not a valid glob.
|
|
286
|
-
*/
|
|
287
|
-
export declare function matchGlob(paths: readonly string[], pattern: string, maxResults: number): {
|
|
288
|
-
readonly matches: readonly string[];
|
|
289
|
-
readonly truncated: boolean;
|
|
290
|
-
};
|
|
291
|
-
/** How much of one command's output was cut, per stream, plus where the full text can be read. */
|
|
292
|
-
export interface ExecTruncation {
|
|
293
|
-
/** Compatibility alias: at least one stream was cut. */
|
|
294
|
-
readonly truncated: boolean;
|
|
295
|
-
readonly stdoutTruncated: boolean;
|
|
296
|
-
readonly stderrTruncated: boolean;
|
|
297
|
-
/** Remote path holding the **full** stdout, present only when stdout was cut. */
|
|
298
|
-
readonly stdoutSpillPath: string | undefined;
|
|
299
|
-
/** Remote path holding the **full** stderr, present only when stderr was cut. */
|
|
300
|
-
readonly stderrSpillPath: string | undefined;
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Read the per-stream truncation fields out of a raw agent `proc.exec` result.
|
|
304
|
-
*
|
|
305
|
-
* Contract (agreed with the Go agent, audit 0052 §P4/§8):
|
|
306
|
-
*
|
|
307
|
-
* - `stdoutTruncated` / `stderrTruncated` are booleans;
|
|
308
|
-
* - `stdoutSpillPath` / `stderrSpillPath` are strings that exist **only** when that stream was cut
|
|
309
|
-
* (`omitempty` on the Go side), so "absent" and "empty" must both read as "no spill";
|
|
310
|
-
* - `truncated` is kept as a deprecated alias meaning `stdoutTruncated || stderrTruncated`.
|
|
311
|
-
*
|
|
312
|
-
* **The legacy fallback is stdout-only, and that is the whole point** (审计 0052 §8). An older agent sends
|
|
313
|
-
* only `truncated`, whose documented meaning is "stdout was cut at maxBytes" (`transport.ts`). Mapping it to
|
|
314
|
-
* *both* streams told the caller that compiler diagnostics on stderr had been cut when nothing said so — and
|
|
315
|
-
* that over-report is what a real agent exposed: `stderrTruncated: false` arrived, and the rendered result
|
|
316
|
-
* still claimed "被截断的流:stdout 与 stderr". Reporting less than the truth is a bug; reporting **more** is
|
|
317
|
-
* a worse one, because it sends the reader to re-run an expensive build or to open a spill file that has
|
|
318
|
-
* nothing to add.
|
|
319
|
-
*
|
|
320
|
-
* `??`-style semantics, never `||`: an explicit `false` is a real answer ("this stream was not cut") and must
|
|
321
|
-
* survive. A caller that genuinely knows stderr was cut says so by sending `stderrTruncated: true`.
|
|
322
|
-
*
|
|
323
|
-
* @param raw - the agent's result object, however malformed or old.
|
|
324
|
-
* @returns the normalized truncation report.
|
|
325
|
-
*/
|
|
326
|
-
export declare function readExecTruncation(raw: unknown): ExecTruncation;
|
|
327
|
-
/** Why a search stopped early. Mirrors the agent's `truncatedReasons` values. */
|
|
328
|
-
export type SearchTruncationReason = 'maxResults' | 'bytesScanned' | 'maxFileBytes' | 'timeout' | 'maxEntries';
|
|
329
|
-
/** How a search ended, in enough detail to tell the caller what to change. */
|
|
330
|
-
export interface SearchTruncation {
|
|
331
|
-
/** Compatibility flag: any bound was hit. */
|
|
332
|
-
readonly truncated: boolean;
|
|
333
|
-
/** Which bounds were hit, de-duplicated and in a stable order. Empty when nothing was cut. */
|
|
334
|
-
readonly reasons: readonly string[];
|
|
335
|
-
/**
|
|
336
|
-
* How many candidate files the filename filters removed, or `undefined` when the agent did not say.
|
|
337
|
-
*
|
|
338
|
-
* This is what makes `include` **observable**: a mistyped filter yields zero matches with every candidate
|
|
339
|
-
* filtered out, which looks identical to "the symbol is not there" unless the count is reported.
|
|
340
|
-
*/
|
|
341
|
-
readonly filesFiltered: number | undefined;
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Normalize a search result's truncation report.
|
|
345
|
-
*
|
|
346
|
-
* Contract (agreed with the Go agent, audit 0052 P7): `truncatedReasons` is a de-duplicated `[]string` whose
|
|
347
|
-
* values are `maxResults` / `bytesScanned` / `maxFileBytes` / `timeout` / `maxEntries`, and `filesFiltered`
|
|
348
|
-
* is an int. Both are **new**, so an older agent returns neither — and then the single `truncated` boolean
|
|
349
|
-
* must still work. `??` (not `||`) keeps an explicit `false` and a legitimate `0` meaningful.
|
|
350
|
-
*
|
|
351
|
-
* An unrecognized reason is kept verbatim rather than dropped: a newer agent naming a bound this build does
|
|
352
|
-
* not know about must not be silently reported as "nothing was truncated".
|
|
353
|
-
*
|
|
354
|
-
* @param raw - the agent's result object, however old or malformed.
|
|
355
|
-
* @returns the normalized report.
|
|
356
|
-
*/
|
|
357
|
-
export declare function readSearchTruncation(raw: unknown): SearchTruncation;
|
|
358
|
-
/**
|
|
359
|
-
* Turn one truncation reason into the change that would actually help.
|
|
360
|
-
*
|
|
361
|
-
* The five bounds are not interchangeable (audit 0052 P7): `maxResults` is fixed by narrowing the *pattern*,
|
|
362
|
-
* `bytesScanned` by narrowing the *paths*, and so on. A single "results were truncated" left the caller to
|
|
363
|
-
* guess, and guessing wrong meant re-running an expensive whole-tree scan.
|
|
364
|
-
*
|
|
365
|
-
* @param reason - a value from the agent's `truncatedReasons`.
|
|
366
|
-
* @returns a model-facing, actionable sentence.
|
|
367
|
-
*/
|
|
368
|
-
export declare function searchTruncationAdvice(reason: string): string;
|
|
369
|
-
//# sourceMappingURL=tool-requests.d.ts.map
|