dsh-remote 0.8.46 → 0.8.48

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 (391) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +361 -361
  3. package/README.md +368 -368
  4. package/cordis.patch.yml +9 -9
  5. package/lib/binding.js +172 -172
  6. package/lib/client.js +3637 -3637
  7. package/lib/credential.js +177 -177
  8. package/lib/deploy-tasks.js +142 -142
  9. package/lib/errors.js +87 -87
  10. package/lib/file-reference.js +457 -457
  11. package/lib/forwards.js +258 -258
  12. package/lib/hostkey.js +108 -108
  13. package/lib/http-transport.js +196 -196
  14. package/lib/ignore.js +202 -156
  15. package/lib/index.js +3779 -3747
  16. package/lib/openssh.js +838 -838
  17. package/lib/paths.js +225 -225
  18. package/lib/pool.js +757 -757
  19. package/lib/registry.js +95 -95
  20. package/lib/remote-fs.js +148 -143
  21. package/lib/routes-fs.js +233 -233
  22. package/lib/search.js +235 -230
  23. package/lib/sftp-surface.js +76 -76
  24. package/lib/sshconfig.js +454 -454
  25. package/lib/sync.js +275 -275
  26. package/lib/tasks.js +95 -95
  27. package/lib/telemetry.js +213 -213
  28. package/lib/update.js +472 -472
  29. package/lib/web-attach.js +850 -850
  30. package/lib/web-deploy-skill.js +205 -205
  31. package/lib/web-deploy.js +694 -694
  32. package/node_modules/asn1/Jenkinsfile +65 -0
  33. package/node_modules/asn1/LICENSE +19 -0
  34. package/node_modules/asn1/README.md +50 -0
  35. package/node_modules/asn1/lib/ber/errors.js +13 -0
  36. package/node_modules/asn1/lib/ber/index.js +27 -0
  37. package/node_modules/asn1/lib/ber/reader.js +262 -0
  38. package/node_modules/asn1/lib/ber/types.js +36 -0
  39. package/node_modules/asn1/lib/ber/writer.js +317 -0
  40. package/node_modules/asn1/lib/index.js +20 -0
  41. package/node_modules/asn1/package.json +31 -0
  42. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  43. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  44. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  45. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  46. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  47. package/node_modules/buildcheck/.eslintrc.js +5 -0
  48. package/node_modules/buildcheck/.github/workflows/ci.yml +88 -0
  49. package/node_modules/buildcheck/.github/workflows/lint.yml +27 -0
  50. package/node_modules/buildcheck/.npmignore +3 -0
  51. package/node_modules/buildcheck/LICENSE +19 -0
  52. package/node_modules/buildcheck/README.md +106 -0
  53. package/node_modules/buildcheck/deps/Find-VisualStudio.cs +250 -0
  54. package/node_modules/buildcheck/lib/findvs.js +361 -0
  55. package/node_modules/buildcheck/lib/index.js +738 -0
  56. package/node_modules/buildcheck/package.json +36 -0
  57. package/node_modules/buildcheck/test/test.js +8 -0
  58. package/node_modules/cpu-features/.eslintrc.js +5 -0
  59. package/node_modules/cpu-features/.github/workflows/ci.yml +74 -0
  60. package/node_modules/cpu-features/.github/workflows/lint.yml +27 -0
  61. package/node_modules/cpu-features/LICENSE +19 -0
  62. package/node_modules/cpu-features/README.md +59 -0
  63. package/node_modules/cpu-features/binding.gyp +16 -0
  64. package/node_modules/cpu-features/buildcheck.js +32 -0
  65. package/node_modules/cpu-features/deps/cpu_features/.clang-format +4 -0
  66. package/node_modules/cpu-features/deps/cpu_features/.dockerignore +31 -0
  67. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/Dockerfile +5 -0
  68. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/aarch64_linux_cmake.yml +30 -0
  69. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_freebsd_cmake.yml +22 -0
  70. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_bazel.yml +26 -0
  71. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_cmake.yml +31 -0
  72. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_macos_cmake.yml +43 -0
  73. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_windows_cmake.yml +25 -0
  74. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/arm_linux_cmake.yml +31 -0
  75. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/clang_format.yml +24 -0
  76. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/mips_linux_cmake.yml +30 -0
  77. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/power_linux_cmake.yml +29 -0
  78. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/riscv_linux_cmake.yml +28 -0
  79. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/s390x_linux_cmake.yml +27 -0
  80. package/node_modules/cpu-features/deps/cpu_features/.grenrc.yml +21 -0
  81. package/node_modules/cpu-features/deps/cpu_features/BUILD.bazel +329 -0
  82. package/node_modules/cpu-features/deps/cpu_features/CMakeLists.txt +261 -0
  83. package/node_modules/cpu-features/deps/cpu_features/CONTRIBUTING.md +23 -0
  84. package/node_modules/cpu-features/deps/cpu_features/LICENSE +230 -0
  85. package/node_modules/cpu-features/deps/cpu_features/README.md +272 -0
  86. package/node_modules/cpu-features/deps/cpu_features/WORKSPACE +19 -0
  87. package/node_modules/cpu-features/deps/cpu_features/bazel/ci/README.md +5 -0
  88. package/node_modules/cpu-features/deps/cpu_features/bazel/platforms.bzl +11 -0
  89. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesConfig.cmake.in +3 -0
  90. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in +3 -0
  91. package/node_modules/cpu-features/deps/cpu_features/cmake/README.md +30 -0
  92. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/Makefile +252 -0
  93. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/README.md +40 -0
  94. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.dot +64 -0
  95. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.svg +312 -0
  96. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/generate_image.sh +7 -0
  97. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/amd64/Dockerfile +48 -0
  98. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/toolchain/Dockerfile +34 -0
  99. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/CMakeLists.txt +22 -0
  100. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/main.cpp +11 -0
  101. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/vagrant/freebsd/Vagrantfile +107 -0
  102. package/node_modules/cpu-features/deps/cpu_features/cmake/googletest.CMakeLists.txt.in +15 -0
  103. package/node_modules/cpu-features/deps/cpu_features/cpu_features.gyp +105 -0
  104. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_cache_info.h +54 -0
  105. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_macros.h +384 -0
  106. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_aarch64.h +259 -0
  107. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_arm.h +121 -0
  108. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_mips.h +74 -0
  109. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_ppc.h +149 -0
  110. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_riscv.h +72 -0
  111. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_s390x.h +108 -0
  112. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_x86.h +288 -0
  113. package/node_modules/cpu-features/deps/cpu_features/include/internal/bit_utils.h +40 -0
  114. package/node_modules/cpu-features/deps/cpu_features/include/internal/cpuid_x86.h +37 -0
  115. package/node_modules/cpu-features/deps/cpu_features/include/internal/filesystem.h +39 -0
  116. package/node_modules/cpu-features/deps/cpu_features/include/internal/hwcaps.h +240 -0
  117. package/node_modules/cpu-features/deps/cpu_features/include/internal/stack_line_reader.h +49 -0
  118. package/node_modules/cpu-features/deps/cpu_features/include/internal/string_view.h +110 -0
  119. package/node_modules/cpu-features/deps/cpu_features/include/internal/windows_utils.h +70 -0
  120. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/CMakeLists.txt +60 -0
  121. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/README.md +4 -0
  122. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.c +205 -0
  123. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.h +320 -0
  124. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/ndk-compat-test.c +12 -0
  125. package/node_modules/cpu-features/deps/cpu_features/patches/0001-Add-Apple-Silicon-Support.patch +456 -0
  126. package/node_modules/cpu-features/deps/cpu_features/scripts/generate_badges.d +165 -0
  127. package/node_modules/cpu-features/deps/cpu_features/scripts/make_release.sh +75 -0
  128. package/node_modules/cpu-features/deps/cpu_features/scripts/run_integration.sh +490 -0
  129. package/node_modules/cpu-features/deps/cpu_features/scripts/test_integration.sh +79 -0
  130. package/node_modules/cpu-features/deps/cpu_features/src/copy.inl +19 -0
  131. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection.inl +86 -0
  132. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection_and_hwcaps.inl +26 -0
  133. package/node_modules/cpu-features/deps/cpu_features/src/equals.inl +22 -0
  134. package/node_modules/cpu-features/deps/cpu_features/src/filesystem.c +62 -0
  135. package/node_modules/cpu-features/deps/cpu_features/src/hwcaps.c +169 -0
  136. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64__base_implementation.inl +88 -0
  137. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_linux_or_android.c +79 -0
  138. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c +82 -0
  139. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_windows.c +138 -0
  140. package/node_modules/cpu-features/deps/cpu_features/src/impl_arm_linux_or_android.c +212 -0
  141. package/node_modules/cpu-features/deps/cpu_features/src/impl_mips_linux_or_android.c +93 -0
  142. package/node_modules/cpu-features/deps/cpu_features/src/impl_ppc_linux.c +163 -0
  143. package/node_modules/cpu-features/deps/cpu_features/src/impl_riscv_linux.c +111 -0
  144. package/node_modules/cpu-features/deps/cpu_features/src/impl_s390x_linux.c +120 -0
  145. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86__base_implementation.inl +2055 -0
  146. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_freebsd.c +68 -0
  147. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_linux_or_android.c +58 -0
  148. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_macos.c +57 -0
  149. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_windows.c +58 -0
  150. package/node_modules/cpu-features/deps/cpu_features/src/stack_line_reader.c +132 -0
  151. package/node_modules/cpu-features/deps/cpu_features/src/string_view.c +192 -0
  152. package/node_modules/cpu-features/deps/cpu_features/src/utils/list_cpu_features.c +461 -0
  153. package/node_modules/cpu-features/deps/cpu_features/test/CMakeLists.txt +114 -0
  154. package/node_modules/cpu-features/deps/cpu_features/test/bit_utils_test.cc +53 -0
  155. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_aarch64_test.cc +396 -0
  156. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_arm_test.cc +384 -0
  157. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_mips_test.cc +176 -0
  158. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_ppc_test.cc +131 -0
  159. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_riscv_test.cc +180 -0
  160. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_s390x_test.cc +82 -0
  161. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_x86_test.cc +1729 -0
  162. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.cc +103 -0
  163. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.h +61 -0
  164. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.cc +52 -0
  165. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.h +31 -0
  166. package/node_modules/cpu-features/deps/cpu_features/test/stack_line_reader_test.cc +132 -0
  167. package/node_modules/cpu-features/deps/cpu_features/test/string_view_test.cc +202 -0
  168. package/node_modules/cpu-features/lib/index.js +5 -0
  169. package/node_modules/cpu-features/package.json +40 -0
  170. package/node_modules/cpu-features/src/binding.cc +151 -0
  171. package/node_modules/cpu-features/test/test.js +12 -0
  172. package/node_modules/nan/.github/workflows/ci.yml +46 -0
  173. package/node_modules/nan/.pre-commit-config.yaml +8 -0
  174. package/node_modules/nan/CHANGELOG.md +605 -0
  175. package/node_modules/nan/CMakeLists.txt +138 -0
  176. package/node_modules/nan/LICENSE.md +9 -0
  177. package/node_modules/nan/README.md +457 -0
  178. package/node_modules/nan/doc/asyncworker.md +146 -0
  179. package/node_modules/nan/doc/buffers.md +54 -0
  180. package/node_modules/nan/doc/callback.md +76 -0
  181. package/node_modules/nan/doc/converters.md +41 -0
  182. package/node_modules/nan/doc/errors.md +226 -0
  183. package/node_modules/nan/doc/json.md +62 -0
  184. package/node_modules/nan/doc/maybe_types.md +583 -0
  185. package/node_modules/nan/doc/methods.md +689 -0
  186. package/node_modules/nan/doc/new.md +147 -0
  187. package/node_modules/nan/doc/node_misc.md +123 -0
  188. package/node_modules/nan/doc/object_wrappers.md +263 -0
  189. package/node_modules/nan/doc/persistent.md +296 -0
  190. package/node_modules/nan/doc/scopes.md +73 -0
  191. package/node_modules/nan/doc/script.md +58 -0
  192. package/node_modules/nan/doc/string_bytes.md +81 -0
  193. package/node_modules/nan/doc/v8_internals.md +211 -0
  194. package/node_modules/nan/doc/v8_misc.md +85 -0
  195. package/node_modules/nan/include_dirs.js +1 -0
  196. package/node_modules/nan/nan.h +3202 -0
  197. package/node_modules/nan/nan_callbacks.h +141 -0
  198. package/node_modules/nan/nan_callbacks_12_inl.h +730 -0
  199. package/node_modules/nan/nan_callbacks_pre_12_inl.h +528 -0
  200. package/node_modules/nan/nan_converters.h +72 -0
  201. package/node_modules/nan/nan_converters_43_inl.h +68 -0
  202. package/node_modules/nan/nan_converters_pre_43_inl.h +42 -0
  203. package/node_modules/nan/nan_define_own_property_helper.h +29 -0
  204. package/node_modules/nan/nan_implementation_12_inl.h +446 -0
  205. package/node_modules/nan/nan_implementation_pre_12_inl.h +263 -0
  206. package/node_modules/nan/nan_json.h +166 -0
  207. package/node_modules/nan/nan_maybe_43_inl.h +360 -0
  208. package/node_modules/nan/nan_maybe_pre_43_inl.h +268 -0
  209. package/node_modules/nan/nan_new.h +340 -0
  210. package/node_modules/nan/nan_object_wrap.h +156 -0
  211. package/node_modules/nan/nan_persistent_12_inl.h +132 -0
  212. package/node_modules/nan/nan_persistent_pre_12_inl.h +242 -0
  213. package/node_modules/nan/nan_private.h +73 -0
  214. package/node_modules/nan/nan_scriptorigin.h +97 -0
  215. package/node_modules/nan/nan_string_bytes.h +305 -0
  216. package/node_modules/nan/nan_typedarray_contents.h +96 -0
  217. package/node_modules/nan/nan_weak.h +453 -0
  218. package/node_modules/nan/package.json +38 -0
  219. package/node_modules/nan/tools/1to2.js +412 -0
  220. package/node_modules/nan/tools/README.md +14 -0
  221. package/node_modules/nan/tools/package.json +19 -0
  222. package/node_modules/safer-buffer/LICENSE +21 -0
  223. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  224. package/node_modules/safer-buffer/Readme.md +156 -0
  225. package/node_modules/safer-buffer/dangerous.js +58 -0
  226. package/node_modules/safer-buffer/package.json +34 -0
  227. package/node_modules/safer-buffer/safer.js +77 -0
  228. package/node_modules/safer-buffer/tests.js +406 -0
  229. package/node_modules/ssh2/.eslintignore +4 -0
  230. package/node_modules/ssh2/.eslintrc.js +5 -0
  231. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  232. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  233. package/node_modules/ssh2/LICENSE +19 -0
  234. package/node_modules/ssh2/README.md +1529 -0
  235. package/node_modules/ssh2/SFTP.md +413 -0
  236. package/node_modules/ssh2/examples/server-chat.js +238 -0
  237. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  238. package/node_modules/ssh2/install.js +27 -0
  239. package/node_modules/ssh2/lib/Channel.js +295 -0
  240. package/node_modules/ssh2/lib/agent.js +1123 -0
  241. package/node_modules/ssh2/lib/client.js +2176 -0
  242. package/node_modules/ssh2/lib/http-agents.js +84 -0
  243. package/node_modules/ssh2/lib/index.js +44 -0
  244. package/node_modules/ssh2/lib/keygen.js +582 -0
  245. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  246. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  247. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  248. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  249. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  250. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  251. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  252. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  253. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  254. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  255. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  256. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  257. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  258. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  259. package/node_modules/ssh2/lib/server.js +1380 -0
  260. package/node_modules/ssh2/lib/utils.js +336 -0
  261. package/node_modules/ssh2/package.json +49 -0
  262. package/node_modules/ssh2/test/common.js +316 -0
  263. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  264. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  265. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  266. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  267. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  268. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  269. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  270. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  271. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  272. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  273. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  274. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  275. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  276. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  277. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  278. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  279. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  280. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  281. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  282. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  283. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  284. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  285. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  286. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  287. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  288. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  289. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  290. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  291. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  292. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  293. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  294. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  295. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  296. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  297. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  298. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  299. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  300. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  301. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  302. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  303. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  304. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  305. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  306. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  307. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  308. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  309. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  310. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  311. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  312. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  313. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  314. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  315. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  316. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  317. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  318. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  319. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  320. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  321. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  322. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  323. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  324. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  325. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  326. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  327. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  328. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  329. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  330. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  331. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  332. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  333. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  334. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  335. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  336. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  337. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  338. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  339. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  340. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  341. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  342. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  343. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  344. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  345. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  346. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  347. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  348. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  349. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  350. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  351. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  352. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  353. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  354. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  355. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  356. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  357. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  358. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  359. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  360. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  361. package/node_modules/ssh2/test/test-exec.js +578 -0
  362. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  363. package/node_modules/ssh2/test/test-keygen.js +60 -0
  364. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  365. package/node_modules/ssh2/test/test-openssh.js +261 -0
  366. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  367. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  368. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  369. package/node_modules/ssh2/test/test-sftp.js +842 -0
  370. package/node_modules/ssh2/test/test-shell.js +109 -0
  371. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  372. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  373. package/node_modules/ssh2/test/test-userauth.js +611 -0
  374. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  375. package/node_modules/ssh2/test/test.js +20 -0
  376. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  377. package/node_modules/ssh2/util/pagent.c +88 -0
  378. package/node_modules/ssh2/util/pagent.exe +0 -0
  379. package/node_modules/tweetnacl/.npmignore +4 -0
  380. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  381. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  382. package/node_modules/tweetnacl/LICENSE +24 -0
  383. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  384. package/node_modules/tweetnacl/README.md +459 -0
  385. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  386. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  387. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  388. package/node_modules/tweetnacl/nacl.js +1175 -0
  389. package/node_modules/tweetnacl/nacl.min.js +1 -0
  390. package/node_modules/tweetnacl/package.json +58 -0
  391. package/package.json +96 -89
package/lib/paths.js CHANGED
@@ -1,225 +1,225 @@
1
- // dsh-remote — pure path / shell helpers (no fs, no ssh).
2
- // Split out of lib/index.js so they are unit-testable without loading the
3
- // plugin. Both POSIX (`/a/b`) and Windows (`D:\Code`, `\\server\share`) forms
4
- // are supported everywhere.
5
-
6
- /** Single-quote one shell argument verbatim. */
7
- export function shq(s) {
8
- return "'" + String(s).replace(/'/g, "'\\''") + "'"
9
- }
10
-
11
- /**
12
- * Normalize a remote path into a clean absolute path, supporting BOTH POSIX
13
- * (`/home/user`) and Windows (`D:\Code`, `C:/Users/x`, `\\server\share`) forms.
14
- *
15
- * - POSIX paths keep `/` separators and a leading `/`.
16
- * - Windows drive paths keep their `X:` prefix and are returned with `\`
17
- * separators (the native form on a Windows remote); a leading `/` is NOT
18
- * added, so `D:\Code` stays `D:\Code` instead of becoming `/D:\Code`.
19
- * - UNC paths (`\\server\share\…`) keep the `\\server\share` prefix.
20
- * - `.` / `..` segments are collapsed in both separator styles.
21
- */
22
- export function normalizeRemotePath(p) {
23
- const s = String(p)
24
- // Windows UNC: \\server\share\…
25
- const unc = s.match(/^(\\\\[^\\]+(?:\\[^\\]+)?)(?:\\|$)(.*)$/s)
26
- if (unc) {
27
- const [prefix, rest] = [unc[1], unc[2]]
28
- const parts = []
29
- for (const seg of rest.split(/[\\/]+/)) {
30
- if (seg === '' || seg === '.') continue
31
- if (seg === '..') { parts.pop(); continue }
32
- parts.push(seg)
33
- }
34
- return parts.length ? prefix + '\\' + parts.join('\\') : prefix
35
- }
36
- // Windows drive: X:\… or X:/…
37
- const drive = s.match(/^([a-zA-Z]:)(?:[\\/]|$)(.*)$/s)
38
- if (drive) {
39
- const [prefix, rest] = [drive[1], drive[2]]
40
- const parts = []
41
- for (const seg of rest.split(/[\\/]+/)) {
42
- if (seg === '' || seg === '.') continue
43
- if (seg === '..') { parts.pop(); continue }
44
- parts.push(seg)
45
- }
46
- return prefix + '\\' + parts.join('\\')
47
- }
48
- // POSIX: /a/b/c
49
- const parts = []
50
- for (const seg of s.split('/')) {
51
- if (seg === '' || seg === '.') continue
52
- if (seg === '..') {
53
- parts.pop()
54
- continue
55
- }
56
- parts.push(seg)
57
- }
58
- return '/' + parts.join('/')
59
- }
60
-
61
- /** Join a remote dir + entry name, honoring the dir's own separator style. */
62
- export function joinRemotePath(dir, name) {
63
- const d = String(dir)
64
- if (!d) return String(name)
65
- if (d.endsWith('/') || d.endsWith('\\')) return d + String(name)
66
- return d + (d.includes('\\') ? '\\' : '/') + String(name)
67
- }
68
-
69
- /** Parent dir of a remote absolute path (string-level; POSIX or Windows). */
70
- export function remoteDirname(p) {
71
- const norm = normalizeRemotePath(p)
72
- // Windows drive/UNC root: D:\ or \\server\share
73
- if (norm === '/' || /^[a-zA-Z]:\\?$/.test(norm) || /^\\\\[^\\]+\\[^\\]+$/.test(norm)) {
74
- // Ensure a drive root ends with a backslash: D: → D:\
75
- const m = norm.match(/^([a-zA-Z]:)$/)
76
- return m ? m[1] + '\\' : norm
77
- }
78
- const sep = norm.includes('\\') ? '\\' : '/'
79
- const idx = norm.lastIndexOf(sep)
80
- if (idx <= 0) {
81
- // Windows drive with a child (D:\Code) → D:\
82
- const m = norm.match(/^([a-zA-Z]:)\\/)
83
- return m ? m[1] + '\\' : sep === '/' && norm.startsWith('/') ? '/' : norm
84
- }
85
- // A parent that is a Windows drive root also needs the trailing backslash.
86
- const parent = norm.slice(0, idx)
87
- if (sep === '\\' && /^[a-zA-Z]:$/.test(parent)) return parent + '\\'
88
- return parent
89
- }
90
-
91
- /** Create every level of a remote dir via SFTP (true mkdir -p: parents AND the
92
- * target itself), working for both POSIX (`/a/b`) and Windows (`D:\a\b`)
93
- * paths. Best effort: an existing or permission-denied level is skipped.
94
- * FILE-oriented callers must pass the parent dir (remoteDirname(filePath)). */
95
- export async function mkdirRemoteDirs(sftp, dir) {
96
- const target = normalizeRemotePath(dir)
97
- const isWin = target.includes('\\')
98
- // Split off a Windows drive prefix (D:) so it is not treated as a segment.
99
- const drive = isWin ? (target.match(/^([a-zA-Z]:)[\\/]?(.*)$/s) || null) : null
100
- const segs = drive ? drive[2].split(/[\\/]/).filter(Boolean) : target.split(/[\\/]/).filter(Boolean)
101
- let cur = isWin ? (drive ? drive[1] + '\\' : '') : ''
102
- // Drive root (D:\) itself, best effort (usually exists).
103
- if (isWin && cur) { try { await sftp.mkdir(cur) } catch { /* exists */ } }
104
- for (const s of segs) {
105
- if (cur) {
106
- if (!cur.endsWith('\\') && !cur.endsWith('/')) cur += isWin ? '\\' : '/'
107
- cur += s
108
- } else {
109
- cur = (isWin ? s + ':' : '/' + s)
110
- }
111
- try { await sftp.mkdir(cur) } catch { /* exists or no perms */ }
112
- }
113
- }
114
-
115
- /**
116
- * Convert an internal remote path (POSIX `/a/b` or Windows `D:\Code`) into the
117
- * path format the SFTP server understands.
118
- *
119
- * Windows OpenSSH's sftp-server accepts POSIX-style paths: a drive letter is
120
- * written `/D:/…` (equivalent to `D:\…`). POSIX paths pass through unchanged.
121
- * UNC paths are kept as-is (the server resolves `\\server\share` itself).
122
- */
123
- export function toSftpPath(p) {
124
- const norm = normalizeRemotePath(p)
125
- const m = norm.match(/^([a-zA-Z]):\\(.*)$/s)
126
- if (m) return '/' + m[1] + ':/' + m[2].replace(/\\/g, '/')
127
- return norm
128
- }
129
-
130
- /**
131
- * Convert a remote path to the form used in SHELL commands on the remote.
132
- *
133
- * On Windows remotes running Git Bash, native `D:\Code` (or `D:/Code`,
134
- * `/D:/Code`, `/d/Code`) becomes the Git-Bash mount form `/d/Code`; a path
135
- * already in Git-Bash form passes through unchanged. UNC (`\\server\share`)
136
- * maps to `//server/share`. POSIX paths are normalized as-is. The conversion
137
- * is syntactic, so it is safe on POSIX remotes too (only unambiguous Windows
138
- * forms are rewritten).
139
- */
140
- export function toShellPath(p) {
141
- let t = String(p || '').replace(/\\/g, '/')
142
- const unc = t.match(/^\/\/([^/]+)(?:\/(.*))?$/)
143
- if (unc) return '//' + unc[1] + (unc[2] ? '/' + unc[2] : '')
144
- const drive = t.match(/^([a-zA-Z]):(\/|$)/) || t.match(/^\/([a-zA-Z]):(\/|$)/)
145
- if (drive) {
146
- t = '/' + drive[1].toLowerCase() + (drive[2] ? '/' : '') + t.slice(drive[0].length)
147
- }
148
- const parts = []
149
- for (const seg of t.split('/')) {
150
- if (seg === '' || seg === '.') continue
151
- if (seg === '..') { parts.pop(); continue }
152
- parts.push(seg)
153
- }
154
- return '/' + parts.join('/')
155
- }
156
-
157
- /**
158
- * Display form of a path for a Windows remote: a Git-Bash mount `/d/Code` (or
159
- * `/D:/Code`, `D:/Code`) renders as `D:\Code`; anything else (POSIX paths,
160
- * native Windows paths) is returned normalized. POSIX remotes always pass
161
- * through unchanged.
162
- */
163
- export function toDisplayPath(p, platform) {
164
- if (platform !== 'windows') return normalizeRemotePath(p)
165
- const t = String(p || '').replace(/\\/g, '/')
166
- // /X:/rest (Win32-OpenSSH SFTP form)
167
- const gs = t.match(/^\/([a-zA-Z]):\/(.*)$/)
168
- if (gs) return gs[1].toUpperCase() + ':\\' + gs[2].replace(/\//g, '\\')
169
- // /x/rest (Git-Bash mount form) and bare /x
170
- const git = t.match(/^\/([a-zA-Z])(?:\/(.*))?$/)
171
- if (git) return git[1].toUpperCase() + ':\\' + (git[2] || '').replace(/\//g, '\\')
172
- // native X:/rest
173
- const drive = t.match(/^([a-zA-Z]):(?:\/(.*))?$/)
174
- if (drive) return drive[1].toUpperCase() + ':\\' + (drive[2] || '').replace(/\//g, '\\')
175
- return t
176
- }
177
-
178
- /** Basename of a remote absolute path (POSIX or Windows). */
179
- export function remotePathBase(p) {
180
- const norm = normalizeRemotePath(p).replace(/[\\/]+$/, '')
181
- const base = norm.split(/[\\/]/).pop()
182
- // Windows drive root (D:\) has no meaningful basename
183
- if (!base || /^[a-zA-Z]:$/.test(base)) return 'workspace'
184
- return base
185
- }
186
-
187
- /** Relative path of `p` under `root` (POSIX form, no leading slash), or null
188
- * when `p` is not inside `root`. Both POSIX and Windows drive paths work
189
- * (Windows is compared in its `/D:/…` POSIX-equivalent form). */
190
- export function relPathUnder(root, p) {
191
- const posix = (x) => {
192
- let n = normalizeRemotePath(x).replace(/[\\/]+$/, '')
193
- const m = n.match(/^([a-zA-Z]):(.*)$/s)
194
- if (m) return '/' + m[1].toLowerCase() + ':/' + (m[2] ? m[2].replace(/\\/g, '/').replace(/^\/+/, '') : '')
195
- return n.replace(/\\/g, '/')
196
- }
197
- const r = posix(root)
198
- const n = posix(p)
199
- if (n === r) return ''
200
- const prefix = r === '/' ? '/' : r + '/'
201
- if (n.startsWith(prefix)) return n.slice(prefix.length)
202
- return null
203
- }
204
-
205
- export function truncate(s, max) {
206
- // A missing/NaN cap is a CONFIG BUG (measured: a bare `new SshPool({...})`
207
- // with no maxOutputChars turned EVERY exec result into a 29-char truncation
208
- // marker — `'x'.length <= undefined` is false, so the "cap" branch always ran
209
- // and `s.length - undefined` printed NaN — silently destroying every remote
210
- // output, including the web-attach startup token). A bad cap must disable
211
- // truncation, not destroy the string.
212
- const limit = Number(max)
213
- if (!Number.isFinite(limit) || limit <= 0) return s
214
- if (s.length <= limit) return s
215
- return s.slice(0, limit) + `\n…[truncated: ${s.length - limit} more chars]`
216
- }
217
-
218
- /** 32-bit string hash rendered in base36 (short, collision-safe enough). */
219
- export function shortHash(s) {
220
- let h = 0
221
- for (let i = 0; i < s.length; i++) {
222
- h = ((h << 5) - h + s.charCodeAt(i)) | 0
223
- }
224
- return (h >>> 0).toString(36)
225
- }
1
+ // dsh-remote — pure path / shell helpers (no fs, no ssh).
2
+ // Split out of lib/index.js so they are unit-testable without loading the
3
+ // plugin. Both POSIX (`/a/b`) and Windows (`D:\Code`, `\\server\share`) forms
4
+ // are supported everywhere.
5
+
6
+ /** Single-quote one shell argument verbatim. */
7
+ export function shq(s) {
8
+ return "'" + String(s).replace(/'/g, "'\\''") + "'"
9
+ }
10
+
11
+ /**
12
+ * Normalize a remote path into a clean absolute path, supporting BOTH POSIX
13
+ * (`/home/user`) and Windows (`D:\Code`, `C:/Users/x`, `\\server\share`) forms.
14
+ *
15
+ * - POSIX paths keep `/` separators and a leading `/`.
16
+ * - Windows drive paths keep their `X:` prefix and are returned with `\`
17
+ * separators (the native form on a Windows remote); a leading `/` is NOT
18
+ * added, so `D:\Code` stays `D:\Code` instead of becoming `/D:\Code`.
19
+ * - UNC paths (`\\server\share\…`) keep the `\\server\share` prefix.
20
+ * - `.` / `..` segments are collapsed in both separator styles.
21
+ */
22
+ export function normalizeRemotePath(p) {
23
+ const s = String(p)
24
+ // Windows UNC: \\server\share\…
25
+ const unc = s.match(/^(\\\\[^\\]+(?:\\[^\\]+)?)(?:\\|$)(.*)$/s)
26
+ if (unc) {
27
+ const [prefix, rest] = [unc[1], unc[2]]
28
+ const parts = []
29
+ for (const seg of rest.split(/[\\/]+/)) {
30
+ if (seg === '' || seg === '.') continue
31
+ if (seg === '..') { parts.pop(); continue }
32
+ parts.push(seg)
33
+ }
34
+ return parts.length ? prefix + '\\' + parts.join('\\') : prefix
35
+ }
36
+ // Windows drive: X:\… or X:/…
37
+ const drive = s.match(/^([a-zA-Z]:)(?:[\\/]|$)(.*)$/s)
38
+ if (drive) {
39
+ const [prefix, rest] = [drive[1], drive[2]]
40
+ const parts = []
41
+ for (const seg of rest.split(/[\\/]+/)) {
42
+ if (seg === '' || seg === '.') continue
43
+ if (seg === '..') { parts.pop(); continue }
44
+ parts.push(seg)
45
+ }
46
+ return prefix + '\\' + parts.join('\\')
47
+ }
48
+ // POSIX: /a/b/c
49
+ const parts = []
50
+ for (const seg of s.split('/')) {
51
+ if (seg === '' || seg === '.') continue
52
+ if (seg === '..') {
53
+ parts.pop()
54
+ continue
55
+ }
56
+ parts.push(seg)
57
+ }
58
+ return '/' + parts.join('/')
59
+ }
60
+
61
+ /** Join a remote dir + entry name, honoring the dir's own separator style. */
62
+ export function joinRemotePath(dir, name) {
63
+ const d = String(dir)
64
+ if (!d) return String(name)
65
+ if (d.endsWith('/') || d.endsWith('\\')) return d + String(name)
66
+ return d + (d.includes('\\') ? '\\' : '/') + String(name)
67
+ }
68
+
69
+ /** Parent dir of a remote absolute path (string-level; POSIX or Windows). */
70
+ export function remoteDirname(p) {
71
+ const norm = normalizeRemotePath(p)
72
+ // Windows drive/UNC root: D:\ or \\server\share
73
+ if (norm === '/' || /^[a-zA-Z]:\\?$/.test(norm) || /^\\\\[^\\]+\\[^\\]+$/.test(norm)) {
74
+ // Ensure a drive root ends with a backslash: D: → D:\
75
+ const m = norm.match(/^([a-zA-Z]:)$/)
76
+ return m ? m[1] + '\\' : norm
77
+ }
78
+ const sep = norm.includes('\\') ? '\\' : '/'
79
+ const idx = norm.lastIndexOf(sep)
80
+ if (idx <= 0) {
81
+ // Windows drive with a child (D:\Code) → D:\
82
+ const m = norm.match(/^([a-zA-Z]:)\\/)
83
+ return m ? m[1] + '\\' : sep === '/' && norm.startsWith('/') ? '/' : norm
84
+ }
85
+ // A parent that is a Windows drive root also needs the trailing backslash.
86
+ const parent = norm.slice(0, idx)
87
+ if (sep === '\\' && /^[a-zA-Z]:$/.test(parent)) return parent + '\\'
88
+ return parent
89
+ }
90
+
91
+ /** Create every level of a remote dir via SFTP (true mkdir -p: parents AND the
92
+ * target itself), working for both POSIX (`/a/b`) and Windows (`D:\a\b`)
93
+ * paths. Best effort: an existing or permission-denied level is skipped.
94
+ * FILE-oriented callers must pass the parent dir (remoteDirname(filePath)). */
95
+ export async function mkdirRemoteDirs(sftp, dir) {
96
+ const target = normalizeRemotePath(dir)
97
+ const isWin = target.includes('\\')
98
+ // Split off a Windows drive prefix (D:) so it is not treated as a segment.
99
+ const drive = isWin ? (target.match(/^([a-zA-Z]:)[\\/]?(.*)$/s) || null) : null
100
+ const segs = drive ? drive[2].split(/[\\/]/).filter(Boolean) : target.split(/[\\/]/).filter(Boolean)
101
+ let cur = isWin ? (drive ? drive[1] + '\\' : '') : ''
102
+ // Drive root (D:\) itself, best effort (usually exists).
103
+ if (isWin && cur) { try { await sftp.mkdir(cur) } catch { /* exists */ } }
104
+ for (const s of segs) {
105
+ if (cur) {
106
+ if (!cur.endsWith('\\') && !cur.endsWith('/')) cur += isWin ? '\\' : '/'
107
+ cur += s
108
+ } else {
109
+ cur = (isWin ? s + ':' : '/' + s)
110
+ }
111
+ try { await sftp.mkdir(cur) } catch { /* exists or no perms */ }
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Convert an internal remote path (POSIX `/a/b` or Windows `D:\Code`) into the
117
+ * path format the SFTP server understands.
118
+ *
119
+ * Windows OpenSSH's sftp-server accepts POSIX-style paths: a drive letter is
120
+ * written `/D:/…` (equivalent to `D:\…`). POSIX paths pass through unchanged.
121
+ * UNC paths are kept as-is (the server resolves `\\server\share` itself).
122
+ */
123
+ export function toSftpPath(p) {
124
+ const norm = normalizeRemotePath(p)
125
+ const m = norm.match(/^([a-zA-Z]):\\(.*)$/s)
126
+ if (m) return '/' + m[1] + ':/' + m[2].replace(/\\/g, '/')
127
+ return norm
128
+ }
129
+
130
+ /**
131
+ * Convert a remote path to the form used in SHELL commands on the remote.
132
+ *
133
+ * On Windows remotes running Git Bash, native `D:\Code` (or `D:/Code`,
134
+ * `/D:/Code`, `/d/Code`) becomes the Git-Bash mount form `/d/Code`; a path
135
+ * already in Git-Bash form passes through unchanged. UNC (`\\server\share`)
136
+ * maps to `//server/share`. POSIX paths are normalized as-is. The conversion
137
+ * is syntactic, so it is safe on POSIX remotes too (only unambiguous Windows
138
+ * forms are rewritten).
139
+ */
140
+ export function toShellPath(p) {
141
+ let t = String(p || '').replace(/\\/g, '/')
142
+ const unc = t.match(/^\/\/([^/]+)(?:\/(.*))?$/)
143
+ if (unc) return '//' + unc[1] + (unc[2] ? '/' + unc[2] : '')
144
+ const drive = t.match(/^([a-zA-Z]):(\/|$)/) || t.match(/^\/([a-zA-Z]):(\/|$)/)
145
+ if (drive) {
146
+ t = '/' + drive[1].toLowerCase() + (drive[2] ? '/' : '') + t.slice(drive[0].length)
147
+ }
148
+ const parts = []
149
+ for (const seg of t.split('/')) {
150
+ if (seg === '' || seg === '.') continue
151
+ if (seg === '..') { parts.pop(); continue }
152
+ parts.push(seg)
153
+ }
154
+ return '/' + parts.join('/')
155
+ }
156
+
157
+ /**
158
+ * Display form of a path for a Windows remote: a Git-Bash mount `/d/Code` (or
159
+ * `/D:/Code`, `D:/Code`) renders as `D:\Code`; anything else (POSIX paths,
160
+ * native Windows paths) is returned normalized. POSIX remotes always pass
161
+ * through unchanged.
162
+ */
163
+ export function toDisplayPath(p, platform) {
164
+ if (platform !== 'windows') return normalizeRemotePath(p)
165
+ const t = String(p || '').replace(/\\/g, '/')
166
+ // /X:/rest (Win32-OpenSSH SFTP form)
167
+ const gs = t.match(/^\/([a-zA-Z]):\/(.*)$/)
168
+ if (gs) return gs[1].toUpperCase() + ':\\' + gs[2].replace(/\//g, '\\')
169
+ // /x/rest (Git-Bash mount form) and bare /x
170
+ const git = t.match(/^\/([a-zA-Z])(?:\/(.*))?$/)
171
+ if (git) return git[1].toUpperCase() + ':\\' + (git[2] || '').replace(/\//g, '\\')
172
+ // native X:/rest
173
+ const drive = t.match(/^([a-zA-Z]):(?:\/(.*))?$/)
174
+ if (drive) return drive[1].toUpperCase() + ':\\' + (drive[2] || '').replace(/\//g, '\\')
175
+ return t
176
+ }
177
+
178
+ /** Basename of a remote absolute path (POSIX or Windows). */
179
+ export function remotePathBase(p) {
180
+ const norm = normalizeRemotePath(p).replace(/[\\/]+$/, '')
181
+ const base = norm.split(/[\\/]/).pop()
182
+ // Windows drive root (D:\) has no meaningful basename
183
+ if (!base || /^[a-zA-Z]:$/.test(base)) return 'workspace'
184
+ return base
185
+ }
186
+
187
+ /** Relative path of `p` under `root` (POSIX form, no leading slash), or null
188
+ * when `p` is not inside `root`. Both POSIX and Windows drive paths work
189
+ * (Windows is compared in its `/D:/…` POSIX-equivalent form). */
190
+ export function relPathUnder(root, p) {
191
+ const posix = (x) => {
192
+ let n = normalizeRemotePath(x).replace(/[\\/]+$/, '')
193
+ const m = n.match(/^([a-zA-Z]):(.*)$/s)
194
+ if (m) return '/' + m[1].toLowerCase() + ':/' + (m[2] ? m[2].replace(/\\/g, '/').replace(/^\/+/, '') : '')
195
+ return n.replace(/\\/g, '/')
196
+ }
197
+ const r = posix(root)
198
+ const n = posix(p)
199
+ if (n === r) return ''
200
+ const prefix = r === '/' ? '/' : r + '/'
201
+ if (n.startsWith(prefix)) return n.slice(prefix.length)
202
+ return null
203
+ }
204
+
205
+ export function truncate(s, max) {
206
+ // A missing/NaN cap is a CONFIG BUG (measured: a bare `new SshPool({...})`
207
+ // with no maxOutputChars turned EVERY exec result into a 29-char truncation
208
+ // marker — `'x'.length <= undefined` is false, so the "cap" branch always ran
209
+ // and `s.length - undefined` printed NaN — silently destroying every remote
210
+ // output, including the web-attach startup token). A bad cap must disable
211
+ // truncation, not destroy the string.
212
+ const limit = Number(max)
213
+ if (!Number.isFinite(limit) || limit <= 0) return s
214
+ if (s.length <= limit) return s
215
+ return s.slice(0, limit) + `\n…[truncated: ${s.length - limit} more chars]`
216
+ }
217
+
218
+ /** 32-bit string hash rendered in base36 (short, collision-safe enough). */
219
+ export function shortHash(s) {
220
+ let h = 0
221
+ for (let i = 0; i < s.length; i++) {
222
+ h = ((h << 5) - h + s.charCodeAt(i)) | 0
223
+ }
224
+ return (h >>> 0).toString(36)
225
+ }