dsh-over-ssh 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -2
  3. package/agents/agent-manifest.json +20 -0
  4. package/agents/linux-amd64/dsh-over-ssh-agent +0 -0
  5. package/agents/linux-arm64/dsh-over-ssh-agent +0 -0
  6. package/cordis.patch.yml +84 -0
  7. package/lib/client.js +6611 -0
  8. package/lib/file-references.js +366 -0
  9. package/lib/fs.js +1368 -0
  10. package/lib/index.js +19034 -0
  11. package/lib/local-bridge-refs.js +16 -0
  12. package/lib/local-bridge.js +16 -0
  13. package/lib/terminal-wrapper.js +294 -0
  14. package/lib/types/src/client/controls.d.ts +131 -0
  15. package/lib/types/src/client/core/card-focus-trap.d.ts +45 -0
  16. package/lib/types/src/client/core/controls.d.ts +164 -0
  17. package/lib/types/src/client/core/latest.d.ts +48 -0
  18. package/lib/types/src/client/core/locale.d.ts +38 -0
  19. package/lib/types/src/client/core/message.d.ts +37 -0
  20. package/lib/types/src/client/core/panel-model.d.ts +134 -0
  21. package/lib/types/src/client/core/portal.d.ts +266 -0
  22. package/lib/types/src/client/core/remote.d.ts +84 -0
  23. package/lib/types/src/client/core/styles.d.ts +458 -0
  24. package/lib/types/src/client/file-tree-io.d.ts +19 -0
  25. package/lib/types/src/client/file-tree.d.ts +271 -0
  26. package/lib/types/src/client/flows/directory-browser.d.ts +587 -0
  27. package/lib/types/src/client/flows/session-directory.d.ts +415 -0
  28. package/lib/types/src/client/flows/workspace-directory-flow.d.ts +480 -0
  29. package/lib/types/src/client/index.d.ts +49 -0
  30. package/lib/types/src/client/locale.d.ts +31 -0
  31. package/lib/types/src/client/panel-model.d.ts +37 -0
  32. package/lib/types/src/client/panel.d.ts +77 -0
  33. package/lib/types/src/client/roots/connection-test.d.ts +69 -0
  34. package/lib/types/src/client/roots/roots-panel-state.d.ts +307 -0
  35. package/lib/types/src/client/roots/roots-panel-view.d.ts +280 -0
  36. package/lib/types/src/client/roots/roots-panel.d.ts +364 -0
  37. package/lib/types/src/client/roots/transfer-panel-view.d.ts +35 -0
  38. package/lib/types/src/client/roots/transfer-panel.d.ts +241 -0
  39. package/lib/types/src/client/roots/transfer-progress.d.ts +67 -0
  40. package/lib/types/src/client/roots-panel-view.d.ts +236 -0
  41. package/lib/types/src/client/roots-panel.d.ts +347 -0
  42. package/lib/types/src/client/session/session-panel-view.d.ts +336 -0
  43. package/lib/types/src/client/session/session-panel.d.ts +322 -0
  44. package/lib/types/src/client/session/session-remote-mark.d.ts +110 -0
  45. package/lib/types/src/client/session/session-row-actions.d.ts +398 -0
  46. package/lib/types/src/client/session-panel.d.ts +152 -0
  47. package/lib/types/src/client/styles.d.ts +252 -0
  48. package/lib/types/src/client/workspace-directory-flow.d.ts +342 -0
  49. package/lib/types/src/config.d.ts +312 -0
  50. package/lib/types/src/file-references.d.ts +25 -0
  51. package/lib/types/src/fs.d.ts +46 -0
  52. package/lib/types/src/host/app/backend.d.ts +170 -0
  53. package/lib/types/src/host/app/recycle-bin/recycle-bin-contract.d.ts +247 -0
  54. package/lib/types/src/host/app/recycle-bin/recycle-bin-move.d.ts +18 -0
  55. package/lib/types/src/host/app/recycle-bin/recycle-bin-service.d.ts +45 -0
  56. package/lib/types/src/host/app/recycle-bin/recycle-bin-world.d.ts +38 -0
  57. package/lib/types/src/host/app/recycle-bin-contract.d.ts +215 -0
  58. package/lib/types/src/host/app/recycle-bin-move.d.ts +18 -0
  59. package/lib/types/src/host/app/recycle-bin-service.d.ts +45 -0
  60. package/lib/types/src/host/app/recycle-bin-world.d.ts +35 -0
  61. package/lib/types/src/host/app/roots/roots-api-connections.d.ts +49 -0
  62. package/lib/types/src/host/app/roots/roots-api-contract.d.ts +369 -0
  63. package/lib/types/src/host/app/roots/roots-api-directories.d.ts +13 -0
  64. package/lib/types/src/host/app/roots/roots-api-http.d.ts +77 -0
  65. package/lib/types/src/host/app/roots/roots-api-long-poll.d.ts +130 -0
  66. package/lib/types/src/host/app/roots/roots-api-projections.d.ts +102 -0
  67. package/lib/types/src/host/app/roots/roots-api-roots.d.ts +13 -0
  68. package/lib/types/src/host/app/roots/roots-api-state.d.ts +22 -0
  69. package/lib/types/src/host/app/roots/roots-api-transfers.d.ts +26 -0
  70. package/lib/types/src/host/app/roots/roots-api.d.ts +55 -0
  71. package/lib/types/src/host/app/roots/user-roots.d.ts +552 -0
  72. package/lib/types/src/host/app/roots-api-connections.d.ts +49 -0
  73. package/lib/types/src/host/app/roots-api-contract.d.ts +339 -0
  74. package/lib/types/src/host/app/roots-api-directories.d.ts +13 -0
  75. package/lib/types/src/host/app/roots-api-http.d.ts +77 -0
  76. package/lib/types/src/host/app/roots-api-projections.d.ts +102 -0
  77. package/lib/types/src/host/app/roots-api-roots.d.ts +13 -0
  78. package/lib/types/src/host/app/roots-api-state.d.ts +22 -0
  79. package/lib/types/src/host/app/roots-api-support.d.ts +182 -0
  80. package/lib/types/src/host/app/roots-api-transfers.d.ts +13 -0
  81. package/lib/types/src/host/app/roots-api.d.ts +55 -0
  82. package/lib/types/src/host/app/routed-fs.d.ts +239 -0
  83. package/lib/types/src/host/app/serialize.d.ts +37 -0
  84. package/lib/types/src/host/app/session-admin/session-admin-context.d.ts +36 -0
  85. package/lib/types/src/host/app/session-admin/session-admin-contract.d.ts +221 -0
  86. package/lib/types/src/host/app/session-admin/session-admin-delete.d.ts +34 -0
  87. package/lib/types/src/host/app/session-admin/session-admin-service.d.ts +40 -0
  88. package/lib/types/src/host/app/session-admin-context.d.ts +36 -0
  89. package/lib/types/src/host/app/session-admin-contract.d.ts +214 -0
  90. package/lib/types/src/host/app/session-admin-delete.d.ts +34 -0
  91. package/lib/types/src/host/app/session-admin-service.d.ts +38 -0
  92. package/lib/types/src/host/app/takeover/takeover-plan.d.ts +227 -0
  93. package/lib/types/src/host/app/takeover/takeover-rows.d.ts +55 -0
  94. package/lib/types/src/host/app/transport/transport-selector.d.ts +98 -0
  95. package/lib/types/src/host/app/transport/transport-service.d.ts +82 -0
  96. package/lib/types/src/host/app/transport-selector.d.ts +98 -0
  97. package/lib/types/src/host/app/transport-service.d.ts +75 -0
  98. package/lib/types/src/host/app/user-roots.d.ts +461 -0
  99. package/lib/types/src/host/domain/bin-location.d.ts +79 -0
  100. package/lib/types/src/host/domain/capability.d.ts +78 -0
  101. package/lib/types/src/host/domain/connection.d.ts +95 -0
  102. package/lib/types/src/host/domain/errors.d.ts +55 -0
  103. package/lib/types/src/host/domain/glob-pattern.d.ts +62 -0
  104. package/lib/types/src/host/domain/literal-text.d.ts +63 -0
  105. package/lib/types/src/host/domain/path-grammar.d.ts +84 -0
  106. package/lib/types/src/host/domain/recycle-bin.d.ts +337 -0
  107. package/lib/types/src/host/domain/root.d.ts +74 -0
  108. package/lib/types/src/host/domain/roots/bin-location.d.ts +91 -0
  109. package/lib/types/src/host/domain/roots/connection.d.ts +106 -0
  110. package/lib/types/src/host/domain/roots/root.d.ts +108 -0
  111. package/lib/types/src/host/domain/roots/route-table.d.ts +102 -0
  112. package/lib/types/src/host/domain/roots/session-roots.d.ts +151 -0
  113. package/lib/types/src/host/domain/roots/ssh-config.d.ts +73 -0
  114. package/lib/types/src/host/domain/route-table.d.ts +80 -0
  115. package/lib/types/src/host/domain/session/session-admin.d.ts +345 -0
  116. package/lib/types/src/host/domain/session/terminal-target.d.ts +136 -0
  117. package/lib/types/src/host/domain/session-admin.d.ts +330 -0
  118. package/lib/types/src/host/domain/shell.d.ts +47 -0
  119. package/lib/types/src/host/domain/ssh-config.d.ts +73 -0
  120. package/lib/types/src/host/domain/terminal-target.d.ts +132 -0
  121. package/lib/types/src/host/domain/tool-requests.d.ts +369 -0
  122. package/lib/types/src/host/domain/transfer/recycle-bin.d.ts +337 -0
  123. package/lib/types/src/host/domain/transfer/transfer.d.ts +260 -0
  124. package/lib/types/src/host/domain/transfer.d.ts +260 -0
  125. package/lib/types/src/host/infra/backend/local-backend.d.ts +84 -0
  126. package/lib/types/src/host/infra/backend/local-version.d.ts +43 -0
  127. package/lib/types/src/host/infra/backend/platform-local-backend.d.ts +89 -0
  128. package/lib/types/src/host/infra/backend/remote-backend.d.ts +239 -0
  129. package/lib/types/src/host/infra/cache/lru.d.ts +52 -0
  130. package/lib/types/src/host/infra/cache/versioned.d.ts +77 -0
  131. package/lib/types/src/host/infra/temp-name.d.ts +19 -0
  132. package/lib/types/src/host/infra/transport/agent/agent-installer.d.ts +121 -0
  133. package/lib/types/src/host/infra/transport/agent/agent-protocol-client.d.ts +132 -0
  134. package/lib/types/src/host/infra/transport/agent/agent-protocol-codec.d.ts +140 -0
  135. package/lib/types/src/host/infra/transport/agent/agent-protocol-errors.d.ts +41 -0
  136. package/lib/types/src/host/infra/transport/agent/agent-protocol-frames.d.ts +197 -0
  137. package/lib/types/src/host/infra/transport/agent/agent-protocol-types.d.ts +564 -0
  138. package/lib/types/src/host/infra/transport/agent/agent-transport.d.ts +418 -0
  139. package/lib/types/src/host/infra/transport/agent-installer.d.ts +121 -0
  140. package/lib/types/src/host/infra/transport/agent-protocol-client.d.ts +123 -0
  141. package/lib/types/src/host/infra/transport/agent-protocol-codec.d.ts +131 -0
  142. package/lib/types/src/host/infra/transport/agent-protocol-errors.d.ts +41 -0
  143. package/lib/types/src/host/infra/transport/agent-protocol-frames.d.ts +197 -0
  144. package/lib/types/src/host/infra/transport/agent-protocol-types.d.ts +509 -0
  145. package/lib/types/src/host/infra/transport/agent-transport.d.ts +353 -0
  146. package/lib/types/src/host/infra/transport/alias-transport.d.ts +206 -0
  147. package/lib/types/src/host/infra/transport/askpass-fs.d.ts +20 -0
  148. package/lib/types/src/host/infra/transport/askpass.d.ts +133 -0
  149. package/lib/types/src/host/infra/transport/command-pool.d.ts +61 -0
  150. package/lib/types/src/host/infra/transport/fs-commands.d.ts +140 -0
  151. package/lib/types/src/host/infra/transport/git-status-route.d.ts +63 -0
  152. package/lib/types/src/host/infra/transport/git-status.d.ts +101 -0
  153. package/lib/types/src/host/infra/transport/node-spawn.d.ts +26 -0
  154. package/lib/types/src/host/infra/transport/session-window.d.ts +51 -0
  155. package/lib/types/src/host/infra/transport/shell-quote.d.ts +59 -0
  156. package/lib/types/src/host/infra/transport/ssh/alias-transport.d.ts +206 -0
  157. package/lib/types/src/host/infra/transport/ssh/askpass-fs.d.ts +20 -0
  158. package/lib/types/src/host/infra/transport/ssh/askpass.d.ts +133 -0
  159. package/lib/types/src/host/infra/transport/ssh/shell-quote.d.ts +62 -0
  160. package/lib/types/src/host/infra/transport/ssh/ssh-argv.d.ts +43 -0
  161. package/lib/types/src/host/infra/transport/ssh/ssh2-transport.d.ts +328 -0
  162. package/lib/types/src/host/infra/transport/ssh-argv.d.ts +43 -0
  163. package/lib/types/src/host/infra/transport/ssh2-transport.d.ts +302 -0
  164. package/lib/types/src/host/infra/transport/transport-base.d.ts +34 -0
  165. package/lib/types/src/host/infra/transport/transport.d.ts +527 -0
  166. package/lib/types/src/host/integration/agent/agent-install-io.d.ts +33 -0
  167. package/lib/types/src/host/integration/agent/agent-preflight.d.ts +56 -0
  168. package/lib/types/src/host/integration/agent/askpass-registry.d.ts +66 -0
  169. package/lib/types/src/host/integration/agent-install-io.d.ts +33 -0
  170. package/lib/types/src/host/integration/agent-preflight.d.ts +56 -0
  171. package/lib/types/src/host/integration/anchor-directory.d.ts +56 -0
  172. package/lib/types/src/host/integration/askpass-registry.d.ts +59 -0
  173. package/lib/types/src/host/integration/bin-root-resolver.d.ts +81 -0
  174. package/lib/types/src/host/integration/connection-test.d.ts +73 -0
  175. package/lib/types/src/host/integration/file-reference-provider.d.ts +115 -0
  176. package/lib/types/src/host/integration/fs/file-reference-provider.d.ts +142 -0
  177. package/lib/types/src/host/integration/fs/fs-provider.d.ts +368 -0
  178. package/lib/types/src/host/integration/fs/git-status-wiring.d.ts +21 -0
  179. package/lib/types/src/host/integration/fs/platform-errors.d.ts +94 -0
  180. package/lib/types/src/host/integration/fs/remote-file-tools.d.ts +369 -0
  181. package/lib/types/src/host/integration/fs/remote-index.d.ts +177 -0
  182. package/lib/types/src/host/integration/fs-provider.d.ts +226 -0
  183. package/lib/types/src/host/integration/lsp/lsp-framing.d.ts +38 -0
  184. package/lib/types/src/host/integration/lsp/lsp-registry.d.ts +67 -0
  185. package/lib/types/src/host/integration/lsp/lsp-session.d.ts +130 -0
  186. package/lib/types/src/host/integration/management-tools.d.ts +64 -0
  187. package/lib/types/src/host/integration/recycle-bin-service.d.ts +247 -0
  188. package/lib/types/src/host/integration/remote/connection-test.d.ts +73 -0
  189. package/lib/types/src/host/integration/remote/remote-face.d.ts +127 -0
  190. package/lib/types/src/host/integration/remote/remote-tool-backend.d.ts +108 -0
  191. package/lib/types/src/host/integration/remote-face.d.ts +127 -0
  192. package/lib/types/src/host/integration/remote-file-tools.d.ts +241 -0
  193. package/lib/types/src/host/integration/remote-home.d.ts +69 -0
  194. package/lib/types/src/host/integration/remote-index.d.ts +165 -0
  195. package/lib/types/src/host/integration/remote-job-tools.d.ts +295 -0
  196. package/lib/types/src/host/integration/remote-tool-backend.d.ts +97 -0
  197. package/lib/types/src/host/integration/remote-tools.d.ts +206 -0
  198. package/lib/types/src/host/integration/root-registry.d.ts +115 -0
  199. package/lib/types/src/host/integration/roots/anchor-directory.d.ts +56 -0
  200. package/lib/types/src/host/integration/roots/bin-root-resolver.d.ts +81 -0
  201. package/lib/types/src/host/integration/roots/remote-home.d.ts +69 -0
  202. package/lib/types/src/host/integration/roots/root-registry.d.ts +144 -0
  203. package/lib/types/src/host/integration/roots/roots-wiring.d.ts +219 -0
  204. package/lib/types/src/host/integration/roots/session-root-index.d.ts +52 -0
  205. package/lib/types/src/host/integration/roots-api.d.ts +407 -0
  206. package/lib/types/src/host/integration/roots-wiring.d.ts +211 -0
  207. package/lib/types/src/host/integration/session/session-api.d.ts +88 -0
  208. package/lib/types/src/host/integration/session/session-bin-lock.d.ts +80 -0
  209. package/lib/types/src/host/integration/session/session-header.d.ts +151 -0
  210. package/lib/types/src/host/integration/session/session-labels.d.ts +56 -0
  211. package/lib/types/src/host/integration/session/session-route-wiring.d.ts +50 -0
  212. package/lib/types/src/host/integration/session-admin-service.d.ts +236 -0
  213. package/lib/types/src/host/integration/session-api.d.ts +81 -0
  214. package/lib/types/src/host/integration/session-bin-lock.d.ts +80 -0
  215. package/lib/types/src/host/integration/session-header.d.ts +118 -0
  216. package/lib/types/src/host/integration/session-labels.d.ts +56 -0
  217. package/lib/types/src/host/integration/session-route-wiring.d.ts +50 -0
  218. package/lib/types/src/host/integration/session-scope.d.ts +113 -0
  219. package/lib/types/src/host/integration/session-tools.d.ts +44 -0
  220. package/lib/types/src/host/integration/strict-arguments.d.ts +79 -0
  221. package/lib/types/src/host/integration/takeover/takeover-api.d.ts +62 -0
  222. package/lib/types/src/host/integration/takeover/takeover-route-wiring.d.ts +60 -0
  223. package/lib/types/src/host/integration/takeover/takeover-service.d.ts +167 -0
  224. package/lib/types/src/host/integration/terminal-manifest.d.ts +94 -0
  225. package/lib/types/src/host/integration/tools/management-tools.d.ts +245 -0
  226. package/lib/types/src/host/integration/tools/remote-job-tools.d.ts +316 -0
  227. package/lib/types/src/host/integration/tools/remote-lsp-tools.d.ts +43 -0
  228. package/lib/types/src/host/integration/tools/remote-tools.d.ts +236 -0
  229. package/lib/types/src/host/integration/tools/session-target.d.ts +52 -0
  230. package/lib/types/src/host/integration/tools/session-tools.d.ts +46 -0
  231. package/lib/types/src/host/integration/tools/strict-arguments.d.ts +79 -0
  232. package/lib/types/src/host/integration/tools/terminal-manifest.d.ts +94 -0
  233. package/lib/types/src/host/integration/transfer/remote-copy.d.ts +66 -0
  234. package/lib/types/src/host/integration/transfer/transfer-adapters.d.ts +48 -0
  235. package/lib/types/src/host/integration/transfer/transfer-service.d.ts +212 -0
  236. package/lib/types/src/host/integration/transfer/transfer-tracker.d.ts +106 -0
  237. package/lib/types/src/host/integration/transfer-adapters.d.ts +44 -0
  238. package/lib/types/src/host/integration/transfer-service.d.ts +164 -0
  239. package/lib/types/src/host/integration/transfer-tracker.d.ts +106 -0
  240. package/lib/types/src/host/integration/user-roots.d.ts +461 -0
  241. package/lib/types/src/index.d.ts +66 -0
  242. package/lib/types/src/local-bridge-refs.d.ts +26 -0
  243. package/lib/types/src/local-bridge.d.ts +36 -0
  244. package/lib/types/src/shared/format.d.ts +13 -0
  245. package/lib/types/src/wiring/connections.d.ts +189 -0
  246. package/lib/types/src/wiring/fs.d.ts +13 -0
  247. package/lib/types/src/wiring/helpers.d.ts +144 -0
  248. package/lib/types/src/wiring/install-memo.d.ts +32 -0
  249. package/lib/types/src/wiring/legacy-dirs.d.ts +62 -0
  250. package/lib/types/src/wiring/package-paths.d.ts +35 -0
  251. package/lib/types/src/wiring/roots.d.ts +21 -0
  252. package/lib/types/src/wiring/state-dir.d.ts +29 -0
  253. package/lib/types/src/wiring/tools.d.ts +35 -0
  254. package/package.json +120 -4
@@ -0,0 +1,369 @@
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