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.
Files changed (247) hide show
  1. package/README.md +10 -10
  2. package/agents/agent-manifest.json +1 -1
  3. package/lib/client.js +363 -314
  4. package/lib/file-references.js +80 -35
  5. package/lib/fs.js +158 -75
  6. package/lib/index.js +4103 -3397
  7. package/lib/terminal-wrapper.js +9 -4
  8. package/lib/types/src/config.d.ts +80 -9
  9. package/lib/types/src/file-references.d.ts +0 -1
  10. package/lib/types/src/host/app/backend.d.ts +9 -1
  11. package/lib/types/src/host/app/recycle-bin/recycle-bin-contract.d.ts +0 -1
  12. package/lib/types/src/host/app/recycle-bin/recycle-bin-service.d.ts +0 -1
  13. package/lib/types/src/host/app/session-admin/session-admin-contract.d.ts +12 -1
  14. package/lib/types/src/host/app/session-admin/session-admin-service.d.ts +0 -1
  15. package/lib/types/src/host/app/transport/transport-selector.d.ts +0 -1
  16. package/lib/types/src/host/app/transport/transport-service.d.ts +0 -1
  17. package/lib/types/src/host/domain/capability.d.ts +0 -1
  18. package/lib/types/src/host/domain/errors.d.ts +0 -1
  19. package/lib/types/src/host/domain/roots/connection.d.ts +0 -1
  20. package/lib/types/src/host/domain/roots/root.d.ts +24 -9
  21. package/lib/types/src/host/domain/roots/session-roots.d.ts +0 -1
  22. package/lib/types/src/host/domain/roots/ssh-config.d.ts +0 -1
  23. package/lib/types/src/host/domain/session/session-admin.d.ts +0 -1
  24. package/lib/types/src/host/domain/transfer/recycle-bin.d.ts +0 -1
  25. package/lib/types/src/host/domain/transfer/transfer.d.ts +0 -1
  26. package/lib/types/src/host/infra/transport/agent/agent-installer.d.ts +0 -1
  27. package/lib/types/src/host/infra/transport/ssh/ssh2-transport.d.ts +0 -1
  28. package/lib/types/src/host/infra/transport/transport-base.d.ts +0 -1
  29. package/lib/types/src/host/infra/transport/transport.d.ts +16 -2
  30. package/lib/types/src/host/integration/agent/agent-preflight.d.ts +0 -1
  31. package/lib/types/src/host/integration/fs/file-reference-provider.d.ts +0 -1
  32. package/lib/types/src/host/integration/fs/fs-provider.d.ts +0 -2
  33. package/lib/types/src/host/integration/transfer/transfer-service.d.ts +0 -1
  34. package/lib/types/src/index.d.ts +23 -1
  35. package/lib/types/src/local-bridge-refs.d.ts +0 -1
  36. package/lib/types/src/local-bridge.d.ts +0 -1
  37. package/lib/types/src/shared/root-keys.d.ts +120 -0
  38. package/lib/types/src/wiring/helpers.d.ts +0 -1
  39. package/package.json +5 -3
  40. package/lib/types/src/client/controls.d.ts +0 -131
  41. package/lib/types/src/client/core/card-focus-trap.d.ts +0 -45
  42. package/lib/types/src/client/core/controls.d.ts +0 -164
  43. package/lib/types/src/client/core/latest.d.ts +0 -48
  44. package/lib/types/src/client/core/locale.d.ts +0 -38
  45. package/lib/types/src/client/core/message.d.ts +0 -37
  46. package/lib/types/src/client/core/panel-model.d.ts +0 -134
  47. package/lib/types/src/client/core/portal.d.ts +0 -266
  48. package/lib/types/src/client/core/remote.d.ts +0 -84
  49. package/lib/types/src/client/core/styles.d.ts +0 -458
  50. package/lib/types/src/client/file-tree-io.d.ts +0 -19
  51. package/lib/types/src/client/file-tree.d.ts +0 -271
  52. package/lib/types/src/client/flows/directory-browser.d.ts +0 -587
  53. package/lib/types/src/client/flows/session-directory.d.ts +0 -415
  54. package/lib/types/src/client/flows/workspace-directory-flow.d.ts +0 -480
  55. package/lib/types/src/client/locale.d.ts +0 -31
  56. package/lib/types/src/client/panel-model.d.ts +0 -37
  57. package/lib/types/src/client/panel.d.ts +0 -77
  58. package/lib/types/src/client/roots/connection-test.d.ts +0 -69
  59. package/lib/types/src/client/roots/roots-panel-state.d.ts +0 -307
  60. package/lib/types/src/client/roots/roots-panel-view.d.ts +0 -280
  61. package/lib/types/src/client/roots/roots-panel.d.ts +0 -364
  62. package/lib/types/src/client/roots/transfer-panel-view.d.ts +0 -35
  63. package/lib/types/src/client/roots/transfer-panel.d.ts +0 -241
  64. package/lib/types/src/client/roots/transfer-progress.d.ts +0 -67
  65. package/lib/types/src/client/roots-panel-view.d.ts +0 -236
  66. package/lib/types/src/client/roots-panel.d.ts +0 -347
  67. package/lib/types/src/client/session/session-panel-view.d.ts +0 -336
  68. package/lib/types/src/client/session/session-panel.d.ts +0 -322
  69. package/lib/types/src/client/session/session-remote-mark.d.ts +0 -110
  70. package/lib/types/src/client/session/session-row-actions.d.ts +0 -398
  71. package/lib/types/src/client/session-panel.d.ts +0 -152
  72. package/lib/types/src/client/styles.d.ts +0 -252
  73. package/lib/types/src/client/workspace-directory-flow.d.ts +0 -342
  74. package/lib/types/src/fs.d.ts +0 -46
  75. package/lib/types/src/host/app/recycle-bin/recycle-bin-move.d.ts +0 -18
  76. package/lib/types/src/host/app/recycle-bin/recycle-bin-world.d.ts +0 -38
  77. package/lib/types/src/host/app/recycle-bin-contract.d.ts +0 -215
  78. package/lib/types/src/host/app/recycle-bin-move.d.ts +0 -18
  79. package/lib/types/src/host/app/recycle-bin-service.d.ts +0 -45
  80. package/lib/types/src/host/app/recycle-bin-world.d.ts +0 -35
  81. package/lib/types/src/host/app/roots/roots-api-connections.d.ts +0 -49
  82. package/lib/types/src/host/app/roots/roots-api-contract.d.ts +0 -369
  83. package/lib/types/src/host/app/roots/roots-api-directories.d.ts +0 -13
  84. package/lib/types/src/host/app/roots/roots-api-http.d.ts +0 -77
  85. package/lib/types/src/host/app/roots/roots-api-long-poll.d.ts +0 -130
  86. package/lib/types/src/host/app/roots/roots-api-projections.d.ts +0 -102
  87. package/lib/types/src/host/app/roots/roots-api-roots.d.ts +0 -13
  88. package/lib/types/src/host/app/roots/roots-api-state.d.ts +0 -22
  89. package/lib/types/src/host/app/roots/roots-api-transfers.d.ts +0 -26
  90. package/lib/types/src/host/app/roots/roots-api.d.ts +0 -55
  91. package/lib/types/src/host/app/roots/user-roots.d.ts +0 -552
  92. package/lib/types/src/host/app/roots-api-connections.d.ts +0 -49
  93. package/lib/types/src/host/app/roots-api-contract.d.ts +0 -339
  94. package/lib/types/src/host/app/roots-api-directories.d.ts +0 -13
  95. package/lib/types/src/host/app/roots-api-http.d.ts +0 -77
  96. package/lib/types/src/host/app/roots-api-projections.d.ts +0 -102
  97. package/lib/types/src/host/app/roots-api-roots.d.ts +0 -13
  98. package/lib/types/src/host/app/roots-api-state.d.ts +0 -22
  99. package/lib/types/src/host/app/roots-api-support.d.ts +0 -182
  100. package/lib/types/src/host/app/roots-api-transfers.d.ts +0 -13
  101. package/lib/types/src/host/app/roots-api.d.ts +0 -55
  102. package/lib/types/src/host/app/routed-fs.d.ts +0 -239
  103. package/lib/types/src/host/app/serialize.d.ts +0 -37
  104. package/lib/types/src/host/app/session-admin/session-admin-context.d.ts +0 -36
  105. package/lib/types/src/host/app/session-admin/session-admin-delete.d.ts +0 -34
  106. package/lib/types/src/host/app/session-admin-context.d.ts +0 -36
  107. package/lib/types/src/host/app/session-admin-contract.d.ts +0 -214
  108. package/lib/types/src/host/app/session-admin-delete.d.ts +0 -34
  109. package/lib/types/src/host/app/session-admin-service.d.ts +0 -38
  110. package/lib/types/src/host/app/takeover/takeover-plan.d.ts +0 -227
  111. package/lib/types/src/host/app/takeover/takeover-rows.d.ts +0 -55
  112. package/lib/types/src/host/app/transport-selector.d.ts +0 -98
  113. package/lib/types/src/host/app/transport-service.d.ts +0 -75
  114. package/lib/types/src/host/app/user-roots.d.ts +0 -461
  115. package/lib/types/src/host/domain/bin-location.d.ts +0 -79
  116. package/lib/types/src/host/domain/connection.d.ts +0 -95
  117. package/lib/types/src/host/domain/glob-pattern.d.ts +0 -62
  118. package/lib/types/src/host/domain/literal-text.d.ts +0 -63
  119. package/lib/types/src/host/domain/path-grammar.d.ts +0 -84
  120. package/lib/types/src/host/domain/recycle-bin.d.ts +0 -337
  121. package/lib/types/src/host/domain/root.d.ts +0 -74
  122. package/lib/types/src/host/domain/roots/bin-location.d.ts +0 -91
  123. package/lib/types/src/host/domain/roots/route-table.d.ts +0 -102
  124. package/lib/types/src/host/domain/route-table.d.ts +0 -80
  125. package/lib/types/src/host/domain/session/terminal-target.d.ts +0 -136
  126. package/lib/types/src/host/domain/session-admin.d.ts +0 -330
  127. package/lib/types/src/host/domain/shell.d.ts +0 -47
  128. package/lib/types/src/host/domain/ssh-config.d.ts +0 -73
  129. package/lib/types/src/host/domain/terminal-target.d.ts +0 -132
  130. package/lib/types/src/host/domain/tool-requests.d.ts +0 -369
  131. package/lib/types/src/host/domain/transfer.d.ts +0 -260
  132. package/lib/types/src/host/infra/backend/local-backend.d.ts +0 -84
  133. package/lib/types/src/host/infra/backend/local-version.d.ts +0 -43
  134. package/lib/types/src/host/infra/backend/platform-local-backend.d.ts +0 -89
  135. package/lib/types/src/host/infra/backend/remote-backend.d.ts +0 -239
  136. package/lib/types/src/host/infra/cache/lru.d.ts +0 -52
  137. package/lib/types/src/host/infra/cache/versioned.d.ts +0 -77
  138. package/lib/types/src/host/infra/temp-name.d.ts +0 -19
  139. package/lib/types/src/host/infra/transport/agent/agent-protocol-client.d.ts +0 -132
  140. package/lib/types/src/host/infra/transport/agent/agent-protocol-codec.d.ts +0 -140
  141. package/lib/types/src/host/infra/transport/agent/agent-protocol-errors.d.ts +0 -41
  142. package/lib/types/src/host/infra/transport/agent/agent-protocol-frames.d.ts +0 -197
  143. package/lib/types/src/host/infra/transport/agent/agent-protocol-types.d.ts +0 -564
  144. package/lib/types/src/host/infra/transport/agent/agent-transport.d.ts +0 -418
  145. package/lib/types/src/host/infra/transport/agent-installer.d.ts +0 -121
  146. package/lib/types/src/host/infra/transport/agent-protocol-client.d.ts +0 -123
  147. package/lib/types/src/host/infra/transport/agent-protocol-codec.d.ts +0 -131
  148. package/lib/types/src/host/infra/transport/agent-protocol-errors.d.ts +0 -41
  149. package/lib/types/src/host/infra/transport/agent-protocol-frames.d.ts +0 -197
  150. package/lib/types/src/host/infra/transport/agent-protocol-types.d.ts +0 -509
  151. package/lib/types/src/host/infra/transport/agent-transport.d.ts +0 -353
  152. package/lib/types/src/host/infra/transport/alias-transport.d.ts +0 -206
  153. package/lib/types/src/host/infra/transport/askpass-fs.d.ts +0 -20
  154. package/lib/types/src/host/infra/transport/askpass.d.ts +0 -133
  155. package/lib/types/src/host/infra/transport/command-pool.d.ts +0 -61
  156. package/lib/types/src/host/infra/transport/fs-commands.d.ts +0 -140
  157. package/lib/types/src/host/infra/transport/git-status-route.d.ts +0 -63
  158. package/lib/types/src/host/infra/transport/git-status.d.ts +0 -101
  159. package/lib/types/src/host/infra/transport/node-spawn.d.ts +0 -26
  160. package/lib/types/src/host/infra/transport/session-window.d.ts +0 -51
  161. package/lib/types/src/host/infra/transport/shell-quote.d.ts +0 -59
  162. package/lib/types/src/host/infra/transport/ssh/alias-transport.d.ts +0 -206
  163. package/lib/types/src/host/infra/transport/ssh/askpass-fs.d.ts +0 -20
  164. package/lib/types/src/host/infra/transport/ssh/askpass.d.ts +0 -133
  165. package/lib/types/src/host/infra/transport/ssh/shell-quote.d.ts +0 -62
  166. package/lib/types/src/host/infra/transport/ssh/ssh-argv.d.ts +0 -43
  167. package/lib/types/src/host/infra/transport/ssh-argv.d.ts +0 -43
  168. package/lib/types/src/host/infra/transport/ssh2-transport.d.ts +0 -302
  169. package/lib/types/src/host/integration/agent/agent-install-io.d.ts +0 -33
  170. package/lib/types/src/host/integration/agent/askpass-registry.d.ts +0 -66
  171. package/lib/types/src/host/integration/agent-install-io.d.ts +0 -33
  172. package/lib/types/src/host/integration/agent-preflight.d.ts +0 -56
  173. package/lib/types/src/host/integration/anchor-directory.d.ts +0 -56
  174. package/lib/types/src/host/integration/askpass-registry.d.ts +0 -59
  175. package/lib/types/src/host/integration/bin-root-resolver.d.ts +0 -81
  176. package/lib/types/src/host/integration/connection-test.d.ts +0 -73
  177. package/lib/types/src/host/integration/file-reference-provider.d.ts +0 -115
  178. package/lib/types/src/host/integration/fs/git-status-wiring.d.ts +0 -21
  179. package/lib/types/src/host/integration/fs/platform-errors.d.ts +0 -94
  180. package/lib/types/src/host/integration/fs/remote-file-tools.d.ts +0 -369
  181. package/lib/types/src/host/integration/fs/remote-index.d.ts +0 -177
  182. package/lib/types/src/host/integration/fs-provider.d.ts +0 -226
  183. package/lib/types/src/host/integration/lsp/lsp-framing.d.ts +0 -38
  184. package/lib/types/src/host/integration/lsp/lsp-registry.d.ts +0 -67
  185. package/lib/types/src/host/integration/lsp/lsp-session.d.ts +0 -130
  186. package/lib/types/src/host/integration/management-tools.d.ts +0 -64
  187. package/lib/types/src/host/integration/recycle-bin-service.d.ts +0 -247
  188. package/lib/types/src/host/integration/remote/connection-test.d.ts +0 -73
  189. package/lib/types/src/host/integration/remote/remote-face.d.ts +0 -127
  190. package/lib/types/src/host/integration/remote/remote-tool-backend.d.ts +0 -108
  191. package/lib/types/src/host/integration/remote-face.d.ts +0 -127
  192. package/lib/types/src/host/integration/remote-file-tools.d.ts +0 -241
  193. package/lib/types/src/host/integration/remote-home.d.ts +0 -69
  194. package/lib/types/src/host/integration/remote-index.d.ts +0 -165
  195. package/lib/types/src/host/integration/remote-job-tools.d.ts +0 -295
  196. package/lib/types/src/host/integration/remote-tool-backend.d.ts +0 -97
  197. package/lib/types/src/host/integration/remote-tools.d.ts +0 -206
  198. package/lib/types/src/host/integration/root-registry.d.ts +0 -115
  199. package/lib/types/src/host/integration/roots/anchor-directory.d.ts +0 -56
  200. package/lib/types/src/host/integration/roots/bin-root-resolver.d.ts +0 -81
  201. package/lib/types/src/host/integration/roots/remote-home.d.ts +0 -69
  202. package/lib/types/src/host/integration/roots/root-registry.d.ts +0 -144
  203. package/lib/types/src/host/integration/roots/roots-wiring.d.ts +0 -219
  204. package/lib/types/src/host/integration/roots/session-root-index.d.ts +0 -52
  205. package/lib/types/src/host/integration/roots-api.d.ts +0 -407
  206. package/lib/types/src/host/integration/roots-wiring.d.ts +0 -211
  207. package/lib/types/src/host/integration/session/session-api.d.ts +0 -88
  208. package/lib/types/src/host/integration/session/session-bin-lock.d.ts +0 -80
  209. package/lib/types/src/host/integration/session/session-header.d.ts +0 -151
  210. package/lib/types/src/host/integration/session/session-labels.d.ts +0 -56
  211. package/lib/types/src/host/integration/session/session-route-wiring.d.ts +0 -50
  212. package/lib/types/src/host/integration/session-admin-service.d.ts +0 -236
  213. package/lib/types/src/host/integration/session-api.d.ts +0 -81
  214. package/lib/types/src/host/integration/session-bin-lock.d.ts +0 -80
  215. package/lib/types/src/host/integration/session-header.d.ts +0 -118
  216. package/lib/types/src/host/integration/session-labels.d.ts +0 -56
  217. package/lib/types/src/host/integration/session-route-wiring.d.ts +0 -50
  218. package/lib/types/src/host/integration/session-scope.d.ts +0 -113
  219. package/lib/types/src/host/integration/session-tools.d.ts +0 -44
  220. package/lib/types/src/host/integration/strict-arguments.d.ts +0 -79
  221. package/lib/types/src/host/integration/takeover/takeover-api.d.ts +0 -62
  222. package/lib/types/src/host/integration/takeover/takeover-route-wiring.d.ts +0 -60
  223. package/lib/types/src/host/integration/takeover/takeover-service.d.ts +0 -167
  224. package/lib/types/src/host/integration/terminal-manifest.d.ts +0 -94
  225. package/lib/types/src/host/integration/tools/management-tools.d.ts +0 -245
  226. package/lib/types/src/host/integration/tools/remote-job-tools.d.ts +0 -316
  227. package/lib/types/src/host/integration/tools/remote-lsp-tools.d.ts +0 -43
  228. package/lib/types/src/host/integration/tools/remote-tools.d.ts +0 -236
  229. package/lib/types/src/host/integration/tools/session-target.d.ts +0 -52
  230. package/lib/types/src/host/integration/tools/session-tools.d.ts +0 -46
  231. package/lib/types/src/host/integration/tools/strict-arguments.d.ts +0 -79
  232. package/lib/types/src/host/integration/tools/terminal-manifest.d.ts +0 -94
  233. package/lib/types/src/host/integration/transfer/remote-copy.d.ts +0 -66
  234. package/lib/types/src/host/integration/transfer/transfer-adapters.d.ts +0 -48
  235. package/lib/types/src/host/integration/transfer/transfer-tracker.d.ts +0 -106
  236. package/lib/types/src/host/integration/transfer-adapters.d.ts +0 -44
  237. package/lib/types/src/host/integration/transfer-service.d.ts +0 -164
  238. package/lib/types/src/host/integration/transfer-tracker.d.ts +0 -106
  239. package/lib/types/src/host/integration/user-roots.d.ts +0 -461
  240. package/lib/types/src/wiring/connections.d.ts +0 -189
  241. package/lib/types/src/wiring/fs.d.ts +0 -13
  242. package/lib/types/src/wiring/install-memo.d.ts +0 -32
  243. package/lib/types/src/wiring/legacy-dirs.d.ts +0 -62
  244. package/lib/types/src/wiring/package-paths.d.ts +0 -35
  245. package/lib/types/src/wiring/roots.d.ts +0 -21
  246. package/lib/types/src/wiring/state-dir.d.ts +0 -29
  247. package/lib/types/src/wiring/tools.d.ts +0 -35
@@ -1,316 +0,0 @@
1
- /**
2
- * Background jobs on the remote host: `remote_exec_background` plus the four job controls.
3
- *
4
- * The transport could already do every one of these things — `AgentTransport.procStart` / `procStatus` /
5
- * `procOutput` / `procKill` / `procList` — and **nothing called them**: a long remote build had to be
6
- * hand-rolled as `nohup … &` plus manual polling, with no exit code, no job identity and no way to cancel.
7
- * These five tools close that gap and mirror the platform's local `job_output` / `job_list` / `job_kill`
8
- * semantics, which is what the caller already knows.
9
- *
10
- * Four facts the wording is built on, each verified in the agent's own source rather than assumed:
11
- *
12
- * - **Jobs die with the connection** (`dsh-over-ssh-agent/internal/proc/jobs.go` module notes: the agent kills
13
- * every job when the ssh channel closes). "Background job" here means "background within this connection",
14
- * never a durable queue, so each description says so instead of letting the caller assume durability.
15
- * - **Nothing is pushed.** Protocol v1's frame discipline has no server-initiated frames, so progress is
16
- * polled. The `wait` parameter below is a bounded poll loop inside the plugin, not a subscription.
17
- * - **A job's output is a bounded ring that drops the OLDEST bytes** (`proc.start`), unlike `proc.exec`,
18
- * which keeps head+tail and spills the rest to a file. There is **no spill file** for a job, so
19
- * `droppedBytes` is the only signal that output has a hole, and `proc.output` adds `lost: true` when the
20
- * requested span itself was already dropped. A renderer that hid either would let a caller read a torn
21
- * log as a complete one — the exact failure the user reported.
22
- * - **`proc.*` needs a Tier 2 agent.** {@link isAgentJobCapable} decides by method presence (the agent's
23
- * capability frame has no `proc` bit), and a transport that fails the check is refused with
24
- * `REMOTE_UNSUPPORTED` instead of silently degrading to a foreground command.
25
- *
26
- * @module dsh-over-ssh/integration/remote-job-tools
27
- */
28
- import type { Context } from '@deepseek-ai/cordis';
29
- import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
30
- import { type SessionRootOutcome } from '../../domain/roots/session-roots.ts';
31
- import type { Transport } from '../../infra/transport/transport.ts';
32
- import type { AgentJobKill, AgentJobOutput, AgentJobStatus, AgentProcStartRequest } from '../../infra/transport/agent/agent-transport.ts';
33
- /** Default wait applied when `wait: true` is set without `timeoutMs`. */
34
- export declare const DEFAULT_JOB_WAIT_MS = 30000;
35
- /** Hard cap on one wait, so a poll loop cannot hold a tool call open indefinitely. */
36
- export declare const MAX_JOB_WAIT_MS = 600000;
37
- /** Poll interval of the wait loop. */
38
- export declare const DEFAULT_JOB_POLL_MS = 500;
39
- /**
40
- * Server-side wait requested per long-poll slice.
41
- *
42
- * 5 s is chosen against the transport's request budget: the slice plus `waitBudget`'s 5 s margin stays
43
- * inside the 15 s default, so a normal wait can never trip the per-request deadline (which is fatal to
44
- * the connection). A finished job returns from the slice immediately, so this only bounds the idle case.
45
- */
46
- export declare const WAIT_SLICE_MS = 5000;
47
- /** Retained-output cap the tool applies when the caller does not ask for one. */
48
- export declare const DEFAULT_JOB_OUTPUT_BYTES: number;
49
- /**
50
- * Largest retained-output cap the tool will pass on.
51
- *
52
- * Pinned to the agent's own `MaxJobOutputBytes` (`dsh-over-ssh-agent/internal/proc/jobs.go`): the agent refuses a
53
- * larger value with `E_TOO_LARGE`, so clamping here keeps the caller inside the contract and lets the echoed
54
- * `maxOutputBytes` in the result be the truth about what was actually applied.
55
- */
56
- export declare const MAX_JOB_OUTPUT_BYTES: number;
57
- /** The remote root one job call targets. */
58
- export interface RemoteJobTarget {
59
- readonly connectionId: string;
60
- readonly root: string;
61
- }
62
- /** One job's state, as the tools expose it. */
63
- export interface RemoteJobView {
64
- readonly id: string;
65
- /** `running` / `exited` / `killed` / `failed`. */
66
- readonly state: string;
67
- readonly command: string;
68
- readonly pid?: number | undefined;
69
- readonly exitCode: number;
70
- readonly signal?: string | undefined;
71
- readonly timedOut: boolean;
72
- readonly startedMs: number;
73
- readonly durationMs: number;
74
- readonly outputBytes: number;
75
- /** Bytes dropped from the **oldest** end of the ring; non-zero means the output has a hole. */
76
- readonly droppedBytes: number;
77
- }
78
- /** One job's output window, as the tools expose it. */
79
- export interface RemoteJobOutputView {
80
- readonly id: string;
81
- readonly state: string;
82
- readonly data: string;
83
- /** Pass this as the next `offset` to get only what is new. */
84
- readonly nextOffset: number;
85
- readonly droppedBytes: number;
86
- readonly totalBytes: number;
87
- /** The requested span was already dropped: `data` is **not** continuous output. */
88
- readonly lost: boolean;
89
- readonly exitCode: number;
90
- readonly signal?: string | undefined;
91
- readonly timedOut: boolean;
92
- }
93
- /** One `remote_exec_background` request, after validation. */
94
- export interface JobStartRequest {
95
- readonly command: string;
96
- /** Root-absolute working directory. */
97
- readonly cwd: string;
98
- readonly env: Readonly<Record<string, string>> | undefined;
99
- /** `undefined` means **no limit** (the agent's `proc.start` treats 0/absent as unlimited). */
100
- readonly timeoutMs: number | undefined;
101
- readonly maxOutputBytes: number;
102
- /** Text written to stdin at start (one-shot). */
103
- readonly stdin?: string;
104
- /** Keep stdin open so `remote_job_stdin` can append later (审计 0030). */
105
- readonly interactive?: boolean;
106
- }
107
- /** What the job tools need, injected so the definitions stay testable without a transport. */
108
- export interface RemoteJobBackend {
109
- /** Resolve an agent working directory to a remote root. */
110
- resolve(cwd: string): RemoteJobTarget | undefined;
111
- /**
112
- * The remote directory this session added with 「添加目录」, when the cwd itself names no remote root.
113
- *
114
- * Same hook as the other tool backends (audit 0086 added it to `remote_exec`/`remote_grep`/`remote_glob` and
115
- * left the job tools behind). Optional so every existing composition and test keeps working.
116
- *
117
- * @param cwd - the agent's session cwd, used as the workspace identity the add action wrote.
118
- * @returns the single added remote root, a refusal naming several, or `none`.
119
- */
120
- resolveSessionRoot?(cwd: string, sessionId?: string): SessionRootOutcome;
121
- /** Start a job and return immediately. */
122
- start(target: RemoteJobTarget, request: JobStartRequest, signal: AbortSignal): Promise<RemoteJobView>;
123
- /**
124
- * One job's state.
125
- *
126
- * `waitMs` asks the agent to block (server-side) up to that long before answering — the v1
127
- * long-poll that turns "60 round trips per wait" into one. Omitted means "answer immediately",
128
- * which is what an agent that predates the field does anyway.
129
- */
130
- status(target: RemoteJobTarget, jobId: string, signal: AbortSignal, waitMs?: number): Promise<RemoteJobView>;
131
- /** One job's output from `offset`; `waitMs` as in {@link status}. */
132
- output(target: RemoteJobTarget, jobId: string, offset: number, signal: AbortSignal, waitMs?: number): Promise<RemoteJobOutputView>;
133
- /** Request termination. */
134
- kill(target: RemoteJobTarget, jobId: string, signal: AbortSignal): Promise<AgentJobKill>;
135
- /**
136
- * Feed a running interactive job's stdin (审计 0030).
137
- *
138
- * Throws `REMOTE_UNSUPPORTED` when the agent predates `proc.stdin` **or** the job was not started with
139
- * `interactive` — both are capability facts the caller can only report, not work around.
140
- */
141
- stdin(target: RemoteJobTarget, jobId: string, request: {
142
- readonly data?: string;
143
- readonly dataBase64?: string;
144
- readonly close?: boolean;
145
- }, signal: AbortSignal): Promise<{
146
- readonly id: string;
147
- readonly bytes: number;
148
- readonly closed: boolean;
149
- }>;
150
- /** Every job this connection has started. */
151
- list(target: RemoteJobTarget, signal: AbortSignal): Promise<readonly RemoteJobView[]>;
152
- /**
153
- * Drop a settled job from the connection's list.
154
- *
155
- * A running job is refused by the agent: forgetting it would lose track of a live process.
156
- */
157
- forget(target: RemoteJobTarget, jobId: string, signal: AbortSignal): Promise<void>;
158
- /** Bounded poll until the job settles; reports how long it waited. */
159
- waitFor(target: RemoteJobTarget, jobId: string, timeoutMs: number, signal: AbortSignal): Promise<{
160
- readonly status: RemoteJobView;
161
- readonly waitedMs: number;
162
- }>;
163
- }
164
- /** The slice of an agent-capable transport the job tools use. */
165
- export interface AgentJobCapable {
166
- procStart(request: AgentProcStartRequest, signal?: AbortSignal): Promise<AgentJobStatus>;
167
- /** `waitMs` is the v1 long-poll budget (server blocks up to that long); omitted = immediate. */
168
- procStatus(id: string, signal?: AbortSignal, waitMs?: number): Promise<AgentJobStatus>;
169
- procOutput(id: string, offset?: number, signal?: AbortSignal, waitMs?: number): Promise<AgentJobOutput>;
170
- procKill(id: string, signal?: AbortSignal): Promise<AgentJobKill>;
171
- procList(signal?: AbortSignal): Promise<readonly AgentJobStatus[]>;
172
- /** `proc.forget`: drop a settled job from the list. Optional — an older agent answers E_METHOD. */
173
- procForget?(id: string, signal?: AbortSignal): Promise<void>;
174
- /** `proc.stdin`: feed a running interactive job (审计 0030). */
175
- procStdin?(id: string, data: string, close: boolean, signal?: AbortSignal): Promise<{
176
- readonly id: string;
177
- readonly bytes: number;
178
- readonly closed: boolean;
179
- }>;
180
- /** `proc.stdin` with base64 support (the transport-level shape the backend forwards to). */
181
- jobStdin?(request: {
182
- readonly id: string;
183
- readonly data?: string;
184
- readonly dataBase64?: string;
185
- readonly close?: boolean;
186
- }, signal?: AbortSignal): Promise<{
187
- readonly id: string;
188
- readonly bytes: number;
189
- readonly closed: boolean;
190
- }>;
191
- /** `proc.stdin` (审计 0030): optional, because an older agent answers E_METHOD for it. */
192
- procStdin?(id: string, data: string, close: boolean, signal?: AbortSignal): Promise<{
193
- readonly id: string;
194
- readonly bytes: number;
195
- readonly closed: boolean;
196
- }>;
197
- }
198
- /** What the backend needs from its owner. All injected, so it is testable without a real host. */
199
- export interface RemoteJobBackendDeps {
200
- /** Resolve a caller's working directory to a remote root. */
201
- readonly resolveRoot: (cwd: string) => RemoteJobTarget | undefined;
202
- /** See {@link RemoteJobBackend.resolveSessionRoot}. */
203
- readonly resolveSessionRoot?: ((cwd: string, sessionId?: string) => SessionRootOutcome) | undefined;
204
- /** Acquire the connection's transport. */
205
- readonly acquire: (connectionId: string) => Promise<Transport>;
206
- /** Poll interval of the wait loop. */
207
- readonly pollIntervalMs?: number;
208
- /** Injectable clock, so a wait's deadline can be tested without sleeping. */
209
- readonly now?: () => number;
210
- /** Injectable sleep, so the wait loop can be tested without waiting. */
211
- readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
212
- }
213
- /**
214
- * Whether a transport can answer the `proc.*` family.
215
- *
216
- * Structural on purpose, and for the same reason `isAgentSearchCapable` is: the agent's capability frame
217
- * carries no `proc` bit (`AgentCapabilities` in `agent-transport.ts`), so the honest question is "does this
218
- * transport implement the methods", not "does it claim a flag". A wrapper or a future transport that speaks
219
- * the same protocol still passes, and a test can supply one.
220
- *
221
- * Method presence is a **necessary** condition, not a sufficient one: an agent older than `proc.start`
222
- * implements none of them, and an agent that implements them but cannot build the Landlock fence answers
223
- * `E_METHOD` / `E_UNSUPPORTED`, which the transport already translates into `REMOTE_UNSUPPORTED`.
224
- *
225
- * @param transport - candidate transport.
226
- * @returns whether every `proc.*` method is present.
227
- */
228
- export declare function isAgentJobCapable(transport: unknown): transport is AgentJobCapable;
229
- /**
230
- * Build the job backend the entry registers.
231
- *
232
- * @param deps - injected host wiring.
233
- * @returns the backend consumed by {@link registerRemoteJobTools}.
234
- */
235
- export declare function createRemoteJobBackend(deps: RemoteJobBackendDeps): RemoteJobBackend;
236
- /** One job rendered as a single line, for the list. */
237
- export declare function formatJobLine(job: RemoteJobView): string;
238
- /** The fields the one-line job status needs; a status and an output window both carry them. */
239
- export interface JobStatusFields {
240
- readonly id: string;
241
- readonly state: string;
242
- readonly exitCode: number;
243
- readonly signal?: string | undefined;
244
- readonly timedOut: boolean;
245
- /** Absent for an output window, which does not report a duration. */
246
- readonly durationMs?: number | undefined;
247
- readonly outputBytes: number;
248
- readonly droppedBytes: number;
249
- }
250
- /** The status line shared by the job tools' renderings. */
251
- export declare function formatJobStatusLine(job: JobStatusFields): string;
252
- /** Model-facing rendering of a started job. */
253
- export declare function formatJobStarted(job: RemoteJobView, cwd: string, maxOutputBytes: number): string;
254
- /** Model-facing rendering of one job's status. */
255
- export declare function formatJobStatus(job: RemoteJobView): string;
256
- /**
257
- * The job-output value as rendered: the window plus what the wait loop learned.
258
- *
259
- * Deliberately the schema's own shape (including `jobId`, and including `running`), so the renderer reads
260
- * exactly what the tool returned rather than a re-projection that could drift from it.
261
- */
262
- export interface JobOutputView {
263
- readonly jobId: string;
264
- readonly state: string;
265
- readonly data: string;
266
- readonly nextOffset: number;
267
- readonly droppedBytes: number;
268
- readonly totalBytes: number;
269
- readonly lost: boolean;
270
- readonly exitCode: number;
271
- readonly signal?: string | undefined;
272
- readonly timedOut: boolean;
273
- readonly running: boolean;
274
- /** Milliseconds the bounded wait actually spent; `0` when the caller did not wait. */
275
- readonly waitedMs: number;
276
- /** Whether the caller asked to wait. */
277
- readonly waited: boolean;
278
- }
279
- /** Model-facing rendering of one job's output window. */
280
- export declare function formatJobOutput(view: JobOutputView): string;
281
- /** Model-facing rendering of a kill request. */
282
- export declare function formatJobKill(result: AgentJobKill): string;
283
- /** Model-facing rendering of the job list. */
284
- export declare function formatJobList(jobs: readonly RemoteJobView[]): string;
285
- /**
286
- * Validate an `env` argument.
287
- *
288
- * The rule is the one `infra/transport/shell-quote.ts` and `domain/tool-requests.ts` already enforce for
289
- * `remote_exec`; the third copy is deliberate only because the two existing ones are private to their
290
- * modules, and it is pinned by a test. Refusing by name beats the alternative the transport used to have,
291
- * where an unusable key was silently dropped.
292
- *
293
- * @param value - the model's `env` argument, however malformed.
294
- * @returns the validated map, or an error naming the offending key.
295
- */
296
- export declare function readJobEnv(value: unknown): {
297
- readonly env: Readonly<Record<string, string>> | undefined;
298
- } | {
299
- readonly error: string;
300
- };
301
- /**
302
- * Build the five job definitions.
303
- *
304
- * @param backend - injected implementations.
305
- * @returns the definitions, ready for `ctx.tools.register`.
306
- */
307
- export declare function remoteJobToolDefinitions(backend: RemoteJobBackend): ToolDefinition[];
308
- /**
309
- * Register the job tools on one context.
310
- *
311
- * @param ctx - host context with the `tools` service.
312
- * @param backend - injected implementations.
313
- * @returns a disposer removing every registration (idempotent).
314
- */
315
- export declare function registerRemoteJobTools(ctx: Context, backend: RemoteJobBackend): () => void;
316
- //# sourceMappingURL=remote-job-tools.d.ts.map
@@ -1,43 +0,0 @@
1
- /**
2
- * `remote_lsp`: ask a language server on the remote host what it knows.
3
- *
4
- * Before this, the only way to learn "is this file broken" was to run the compiler and parse its text
5
- * output. That works, but the parsing is where the mistakes are, and a compiler reports the whole project
6
- * when you changed one file. A language server answers about one document, in structured form.
7
- *
8
- * The server runs **on the remote host**, because that is where the project and its dependencies are. The
9
- * agent spawns it and moves bytes; the framing and JSON-RPC live in `../lsp/`.
10
- *
11
- * @module dsh-over-ssh/host/integration/tools/remote-lsp-tools
12
- */
13
- import type { Context } from '@deepseek-ai/cordis';
14
- import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
15
- import { defaultServerFor, type LspRegistry } from '../lsp/lsp-registry.ts';
16
- import { type RemoteFileBackend } from '../fs/remote-file-tools.ts';
17
- /** What the LSP tool needs from its owner. */
18
- export interface RemoteLspToolDeps {
19
- readonly backend: RemoteFileBackend;
20
- readonly registry: LspRegistry;
21
- }
22
- /** One diagnostic as the tool reports it (1-based, like every line number a caller sees). */
23
- export interface DiagnosticView {
24
- readonly line: number;
25
- readonly column: number;
26
- readonly endLine: number;
27
- readonly endColumn: number;
28
- readonly severity: string;
29
- readonly message: string;
30
- readonly source?: string;
31
- }
32
- /** Render a diagnostic list for the model. */
33
- export declare function formatDiagnostics(path: string, diagnostics: readonly DiagnosticView[]): string;
34
- export declare function remoteLspToolDefinitions(deps: RemoteLspToolDeps): readonly ToolDefinition[];
35
- /** Flatten `Hover.contents` (string | MarkupContent | MarkedString[]) to plain text. */
36
- export declare function hoverText(result: unknown): string;
37
- /** Flatten `Definition` (`Location | Location[] | LocationLink[]`) to `path:line:column` strings. */
38
- export declare function definitionLocations(result: unknown): string[];
39
- /** Register `remote_lsp` on the plugin context. */
40
- export declare function registerRemoteLspTools(ctx: Context, deps: RemoteLspToolDeps): () => void;
41
- /** Re-exported for the wiring, which needs to build the registry without importing the lsp module. */
42
- export { defaultServerFor };
43
- //# sourceMappingURL=remote-lsp-tools.d.ts.map
@@ -1,236 +0,0 @@
1
- /**
2
- * The agent-facing tool surface: `remote_grep`, `remote_glob`, `remote_exec`.
3
- *
4
- * Before this module the plugin could do everything *for the user* (files, terminal, completion) but exposed
5
- * nothing *to the model*: a turn could not search or run anything on the remote host. These three tools close
6
- * that hole, and every one of them is bounded and reports its truncation.
7
- *
8
- * Targeting: a tool call runs on behalf of one agent, so the agent's session cwd decides which registered root
9
- * answers — the same rule the file-reference provider uses. A cwd outside every root is an error, not a
10
- * silent fallback to the local machine.
11
- *
12
- * **Path spelling is one rule for every tool** (audit 0052 P1/P2): `cwd` / `path` accept an absolute path
13
- * inside the root *or* a root-relative one, resolved by `resolveUnderRoot`. An absolute path outside the root
14
- * is refused by name instead of being silently re-rooted, and `..` folds without leaving the root. All three
15
- * tools say so in their parameter descriptions, because the previous wording ("relative to the workspace
16
- * root") described one contract while the host enforced another.
17
- *
18
- * **Remote calls are serial within a session** (audit 0052 P5): `Promise.all` over several remote calls
19
- * produces no overlap. That is deliberate for a shared build server (concurrent `make` invocations trample
20
- * each other), and every tool says so instead of leaving the caller to discover it by timing three sleeps.
21
- *
22
- * @module dsh-over-ssh/integration/remote-tools
23
- */
24
- import type { Context } from '@deepseek-ai/cordis';
25
- import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
26
- import { type SessionRootOutcome } from '../../domain/roots/session-roots.ts';
27
- import { type ExecRequest, type GlobRequest, type GrepRequest, type GrepOutcome, type SearchTruncation } from '../../domain/tool-requests.ts';
28
- /** The remote root one call targets. */
29
- export interface RemoteToolTarget {
30
- readonly connectionId: string;
31
- readonly root: string;
32
- }
33
- /** Result of a glob/listing call. */
34
- export interface GlobOutcome {
35
- readonly paths: readonly string[];
36
- readonly truncated: boolean;
37
- readonly strategy: string;
38
- }
39
- /**
40
- * Result of a command call.
41
- *
42
- * The per-stream fields are **optional on purpose**: they are what a current agent reports, and an older
43
- * agent (or the shell transports, which report one `truncated` for the whole result) simply omits them.
44
- * {@link readExecTruncation} normalizes both shapes, so nothing here has to guess.
45
- */
46
- export interface ExecOutcome {
47
- readonly exitCode: number;
48
- /**
49
- * The signal that ended the command, or `null`/absent when it exited on its own.
50
- *
51
- * Together with {@link timedOut} this is what makes `exitCode = -1` readable: the code alone cannot say
52
- * whether the deadline fired or the process was signalled (audit 0064 P4).
53
- */
54
- readonly signal?: string | null | undefined;
55
- /**
56
- * Whether the answering transport's own deadline ended the command.
57
- *
58
- * `true` does **not** claim the remote process is dead — only that this plugin stopped waiting, which is
59
- * exactly what its `timeoutMs` description promises.
60
- */
61
- readonly timedOut?: boolean | undefined;
62
- /**
63
- * Tier 1 only: the command was stopped locally (deadline or cancellation) but the host has no agent, so
64
- * nothing can confirm the remote process group died. Protocol D3's `cancel` frame has no Tier 1 equivalent;
65
- * this is the honest report of that limitation. The error/exit code is untouched.
66
- */
67
- readonly remoteMayStillRun?: boolean | undefined;
68
- /** Human-readable explanation accompanying {@link remoteMayStillRun}. */
69
- readonly hint?: string | undefined;
70
- readonly stdout: string;
71
- readonly stderr: string;
72
- readonly durationMs: number;
73
- /** Deprecated single flag: at least one stream was cut. */
74
- readonly truncated: boolean;
75
- /** Whether **stdout** was cut (agent `proc.exec` `stdoutTruncated`). */
76
- readonly stdoutTruncated?: boolean | undefined;
77
- /** Whether **stderr** was cut (agent `proc.exec` `stderrTruncated`). */
78
- readonly stderrTruncated?: boolean | undefined;
79
- /** Remote path holding the full stdout; present only when stdout was cut. */
80
- readonly stdoutSpillPath?: string | undefined;
81
- /** Remote path holding the full stderr; present only when stderr was cut. */
82
- readonly stderrSpillPath?: string | undefined;
83
- }
84
- /** Everything the tools need, injected so the definitions stay testable without transports. */
85
- export interface RemoteToolBackend {
86
- /**
87
- * Resolve an agent working directory to a remote root.
88
- *
89
- * @param cwd - the agent's session cwd.
90
- * @returns the target, or `undefined` when the cwd is outside every remote root.
91
- */
92
- resolve(cwd: string): RemoteToolTarget | undefined;
93
- /**
94
- * The remote directories **this session** added with 「添加目录」, as a fallback target.
95
- *
96
- * A session opened on a local folder has no cwd inside any remote root, so `resolve` answers `undefined`
97
- * for it even after the user added a remote directory to that very session. This hook is how that
98
- * directory becomes usable: the rule itself lives in `domain/roots/session-roots.ts` (pure, offline-tested),
99
- * and this seam only supplies the persisted entries.
100
- *
101
- * Optional so every existing composition and test keeps working: absent means "no session fallback",
102
- * which is exactly the pre-existing behaviour.
103
- *
104
- * @param cwd - the agent's session cwd, used as the workspace identity the add action wrote.
105
- * @returns the single added remote root, a refusal naming several, or `none`.
106
- */
107
- resolveSessionRoot?(cwd: string, sessionId?: string): SessionRootOutcome;
108
- /** Search one remote root. */
109
- grep(target: RemoteToolTarget, request: GrepRequest, signal: AbortSignal): Promise<GrepOutcome>;
110
- /** Enumerate one remote root and match paths. */
111
- glob(target: RemoteToolTarget, request: GlobRequest, signal: AbortSignal): Promise<GlobOutcome>;
112
- /** Run one command on the remote host. */
113
- exec(target: RemoteToolTarget, request: ExecRequest, signal: AbortSignal): Promise<ExecOutcome>;
114
- }
115
- /**
116
- * Build the tool definitions.
117
- *
118
- * @param backend - injected implementations.
119
- * @returns the three definitions, ready for `ctx.tools.register`.
120
- */
121
- export declare function remoteToolDefinitions(backend: RemoteToolBackend): ToolDefinition[];
122
- /** The grep value as rendered: the outcome plus the echo fields the schema also carries. */
123
- export interface GrepView extends GrepOutcome {
124
- /** Filters the search was built with (empty when none). */
125
- readonly include?: readonly string[] | undefined;
126
- /** The root-absolute directory that was searched. */
127
- readonly path?: string | undefined;
128
- /**
129
- * Which bounds stopped the search (agent `truncatedReasons`), flattened onto the value because that is the
130
- * shape the output schema exposes. Empty/absent means the answering tier could not say.
131
- */
132
- readonly truncatedReasons?: readonly string[] | undefined;
133
- /** Candidate files the `include` filters removed, when the agent reported it. */
134
- readonly filesFiltered?: number | undefined;
135
- /** The structured report, when a caller has one in hand (the backend's own outcome). */
136
- readonly truncation?: SearchTruncation | undefined;
137
- /** Whether the search distinguished case; echoed because it changes what "no matches" means. */
138
- readonly caseSensitive?: boolean | undefined;
139
- /** Whether the search dropped the ignore rules it could apply. */
140
- readonly noIgnore?: boolean | undefined;
141
- }
142
- /** The glob value as rendered: the outcome plus the semantics echo and the hint. */
143
- export interface GlobView extends GlobOutcome {
144
- /** The pattern as the caller wrote it. */
145
- readonly pattern?: string | undefined;
146
- /** The root-absolute directory that was enumerated. */
147
- readonly path?: string | undefined;
148
- /** How the pattern was interpreted (`glob`). */
149
- readonly matchSemantics?: string | undefined;
150
- /** Actionable note when zero paths came back. */
151
- readonly hint?: string | undefined;
152
- }
153
- /**
154
- * The note a zero-result glob gets.
155
- *
156
- * The rules that surprise callers are the anchoring ones, so an empty answer names them instead of leaving the
157
- * reader to guess whether the pattern was wrong or the files are absent:
158
- *
159
- * - a pattern without `/` matches the **file name** at any depth, not a substring of the whole path;
160
- * - a pattern with `/` is anchored at the enumerated directory, and `*` does not cross `/`;
161
- * - paths are relative to the enumerated directory, so a leading `/` in the pattern matches nothing.
162
- *
163
- * A non-empty result gets no note: a glob pattern matching like a glob is not worth a sentence.
164
- *
165
- * @param pattern - the pattern as the caller wrote it.
166
- * @param matchCount - how many paths came back.
167
- * @returns the hint, or `undefined` when there is nothing worth saying.
168
- */
169
- export declare function globHint(pattern: string, matchCount: number): string | undefined;
170
- /**
171
- * Explain a failure that is really about the working directory.
172
- *
173
- * The user-visible symptom this addresses (audit 0052 P1): an unusable `cwd` surfaced as
174
- * `E_IO:无法启动进程:fork/exec /bin/sh: no such file or directory`, which reads as "the remote host has no
175
- * shell" and sends the reader off to debug the SSH environment instead of the path they passed. The message
176
- * below names the directory instead.
177
- *
178
- * **Why this is a message and not a pre-flight `stat`.** Two reasons, both deliberate:
179
- *
180
- * 1. A stat costs a full round trip on every single command, including the overwhelming majority that use a
181
- * valid cwd; and it would still race (the directory can vanish between the check and the `chdir`).
182
- * 2. The signature is unambiguous: `fork/exec` failing on the shell binary is what Go's `exec.Cmd` produces
183
- * when `Dir` cannot be entered, and the shell transports emit `cd: … No such file or directory` from the
184
- * `cd` prefix `scriptPrefixes` builds. Both are matched below.
185
- *
186
- * It is worded as a **likely** cause rather than a diagnosis, because the plugin has not stat'd the path.
187
- *
188
- * @param cwd - the root-absolute directory the command was asked to run in.
189
- * @param text - the failure text: the agent error's message, or the command's stderr.
190
- * @param failed - whether the command actually failed (a thrown error counts).
191
- * @param requested - whether the caller named a `cwd` at all; without one there is nothing to explain.
192
- * @returns a model-facing explanation, or `undefined` when the failure is not cwd-shaped.
193
- */
194
- export declare function cwdFailureHint(cwd: string, text: string, failed: boolean, requested: boolean): string | undefined;
195
- /** Model-facing rendering of a search outcome. */
196
- export declare function formatGrep(outcome: GrepView): string;
197
- /**
198
- * The truncation paragraph: which bound was hit, and what to change.
199
- *
200
- * Exported for the same reason as the renderers: the wording is the contract. Note what it deliberately does
201
- * **not** say — there is no offset, cursor or page parameter, because the agent keeps no server-side state
202
- * between calls, so "continue from where you stopped" is not an option and must not be implied.
203
- *
204
- * @param truncation - the normalized report, when the answering tier could provide one.
205
- * @returns zero or more model-facing lines.
206
- */
207
- export declare function truncationLines(truncation: SearchTruncation | undefined): string[];
208
- /** Model-facing rendering of a glob outcome. */
209
- export declare function formatGlob(outcome: GlobView): string;
210
- /**
211
- * The exec value as rendered: the outcome plus the cwd diagnosis the tool adds.
212
- *
213
- * `cwdFailure` lives on the **rendered value**, not on {@link ExecOutcome}: the outcome is what the backend
214
- * reported, while this is the tool layer's own explanation of it.
215
- */
216
- export interface ExecView extends ExecOutcome {
217
- /** Set when the command failed with the signature of an unusable `cwd`. */
218
- readonly cwdFailure?: string | undefined;
219
- }
220
- /**
221
- * Model-facing rendering of a command outcome.
222
- *
223
- * Truncation is reported **per stream** (audit 0052 P4): "output was cut" left the reader unable to tell
224
- * whether the compiler's diagnostics in stderr were complete. When the agent spilled a stream, the message
225
- * names the remote path holding the full text so the model can go read it instead of re-running a build.
226
- */
227
- export declare function formatExec(outcome: ExecView): string;
228
- /**
229
- * Register the tools on one context.
230
- *
231
- * @param ctx - host context with the `tools` service.
232
- * @param backend - injected implementations.
233
- * @returns a disposer removing every registration (idempotent).
234
- */
235
- export declare function registerRemoteTools(ctx: Context, backend: RemoteToolBackend): () => void;
236
- //# sourceMappingURL=remote-tools.d.ts.map
@@ -1,52 +0,0 @@
1
- /**
2
- * Which remote root one tool call targets — the rule, in one place.
3
- *
4
- * Four tool modules (`remote-tools`, `remote-job-tools`, `management-tools`, `fs/remote-file-tools`) ask the
5
- * same two questions in the same order, and each used to carry its own copy of the answer. The copies were
6
- * still in sync, which is exactly the state that makes a divergence invisible: the next fix to one of them
7
- * (a new refusal, a new identity rule) would silently apply to one tool family and not the others. The
8
- * messages are model-facing, so a divergence is a behaviour change, not a cosmetic one.
9
- *
10
- * The rule itself (ADR-0012/0013):
11
- *
12
- * 1. **The session cwd decides** when it names a remote root. A session that lives on a remote workspace keeps
13
- * targeting that workspace; nothing about the pre-existing behaviour moves.
14
- * 2. **Otherwise, the remote directories this session added with 「添加目录」** are the candidates: exactly one
15
- * is used, several are refused by name rather than guessed. This is what makes a session opened on a local
16
- * folder able to reach the remote directory the user explicitly added to it.
17
- *
18
- * The caller supplies the two seams because each tool family has its own backend type; the ordering, the
19
- * refusals and their wording are owned here.
20
- *
21
- * @module dsh-over-ssh/integration/tools/session-target
22
- */
23
- import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
24
- import { type SessionRootOutcome, type SessionRootTarget } from '../../domain/roots/session-roots.ts';
25
- /** What the resolver needs from one tool family's backend. */
26
- export interface SessionTargetSeams<T> {
27
- /** Resolve a session cwd to a target when the cwd itself names a remote root. */
28
- readonly resolve: (cwd: string) => T | undefined;
29
- /** The 「添加目录」 fallback; absent means "no session fallback", the pre-ADR-0013 behaviour. */
30
- readonly resolveSessionRoot?: ((cwd: string, sessionId?: string) => SessionRootOutcome) | undefined;
31
- /**
32
- * Turn a session-added root into the family's own target shape.
33
- *
34
- * Needed because a session root carries no `writable` flag (the domain rule deliberately ignores it) while
35
- * the file tools require one; a family without extra fields omits this and gets the target as-is.
36
- */
37
- readonly adapt?: ((target: SessionRootTarget) => T) | undefined;
38
- }
39
- /** The refusal when the call has no session cwd at all. */
40
- export declare const NO_SESSION_CWD = "\u65E0\u6CD5\u786E\u5B9A\u8C03\u7528\u65B9\u7684\u8FDC\u7AEF\u6839\uFF1A\u8BE5\u5DE5\u5177\u9700\u8981 agent \u7684\u4F1A\u8BDD\u5DE5\u4F5C\u76EE\u5F55";
41
- /** The refusal when the cwd names no root and the session added none (or several). */
42
- export declare function noRemoteRootMessage(cwd: string): string;
43
- /**
44
- * Resolve the caller's target, or fail loudly.
45
- *
46
- * @param exec - tool run context (carries the calling agent and therefore the session).
47
- * @param seams - the family's `resolve` / `resolveSessionRoot` / `adapt`.
48
- * @returns the target the call must use.
49
- * @throws Error naming why no single remote root could be chosen.
50
- */
51
- export declare function resolveSessionTarget<T>(exec: ToolRunContext, seams: SessionTargetSeams<T>): T;
52
- //# sourceMappingURL=session-target.d.ts.map