better-dsh 0.3.1-b → 0.3.1-e

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 (60) hide show
  1. package/cordis.patch.yml +13 -8
  2. package/lib/BrowserWebSocketTransport.js +4 -0
  3. package/lib/{BrowserWebSocketTransport-wm99h94r.js → BrowserWebSocketTransport2.js} +1 -1
  4. package/lib/LaunchOptions.js +4 -0
  5. package/lib/{LaunchOptions-iE9M-STS.js → LaunchOptions2.js} +1 -1
  6. package/lib/{NodeWebSocketTransport-D9ysYGLM.js → NodeWebSocketTransport.js} +2 -2
  7. package/lib/NodeWebSocketTransport2.js +4 -0
  8. package/lib/{bidi-CaQeBZHY.js → bidi.js} +4 -4
  9. package/lib/compaction/index.d.ts +1 -1
  10. package/lib/compaction/index.js +1 -1
  11. package/lib/failover/index.d.ts +1 -1
  12. package/lib/failover/index.js +1 -1
  13. package/lib/fs-aware/sandbox-plugin.js +1 -1
  14. package/lib/{index-browser-CJzxT9Vi.js → index-browser.js} +6 -6
  15. package/lib/index.d.ts +1 -1
  16. package/lib/index.js +49 -20
  17. package/lib/kernel-env.js +1 -1
  18. package/lib/{lsp-server-registry-BcdkHROD.js → lsp-server-registry2.js} +1 -1
  19. package/lib/{main-uqGqYYnA.js → main.js} +1 -1
  20. package/lib/{main-taSMz1KX.js → main2.js} +1 -1
  21. package/lib/mobile/plugin.d.ts +2 -2
  22. package/lib/mobile/plugin.js +2 -2
  23. package/lib/{puppeteer-core-C-4NyOpY.js → puppeteer-core.js} +8 -8
  24. package/lib/py-sdk.js +1 -1
  25. package/lib/remote/helper-bin/MANIFEST.json +7 -7
  26. package/lib/remote/helper-bin/aarch64-apple-darwin/BUILT-VER +1 -1
  27. package/lib/remote/helper-bin/aarch64-apple-darwin/superd-run +0 -0
  28. package/lib/remote/helper-bin/aarch64-unknown-linux-musl/BUILT-VER +1 -1
  29. package/lib/remote/helper-bin/aarch64-unknown-linux-musl/superd-run +0 -0
  30. package/lib/remote/helper-bin/x86_64-pc-windows-gnu/BUILT-VER +1 -1
  31. package/lib/remote/helper-bin/x86_64-pc-windows-gnu/superd-run.exe +0 -0
  32. package/lib/remote/helper-bin/x86_64-unknown-linux-musl/BUILT-VER +1 -1
  33. package/lib/remote/helper-bin/x86_64-unknown-linux-musl/superd-run +0 -0
  34. package/lib/remote/plugin.d.ts +23 -4
  35. package/lib/remote/plugin.js +226 -88
  36. package/lib/url-schemes/index.d.ts +1 -1
  37. package/lib/url-schemes/index.js +11 -11
  38. package/lib/{wasm_bg-CNXhHjVg.js → wasm_bg.js} +1 -1
  39. package/lib/web-password.d.ts +1 -1
  40. package/lib/web-password.js +1 -1
  41. package/lib/web-trust.d.ts +2 -2
  42. package/lib/web-trust.js +2 -2
  43. package/lib/{web-trust-Dej_RI2B.d.ts → web-trust2.d.ts} +1 -1
  44. package/lib/{web-trust-D6gJpUMf.js → web-trust2.js} +20 -8
  45. package/lib/welcome-notice.d.ts +1 -1
  46. package/lib/welcome-notice.js +1 -1
  47. package/package.json +1 -1
  48. package/lib/BrowserWebSocketTransport-D1aFReu_.js +0 -4
  49. package/lib/LaunchOptions-0Mr6meJc.js +0 -4
  50. package/lib/NodeWebSocketTransport-BRLjmu2R.js +0 -4
  51. /package/lib/{chunk-DQxbwPpZ.js → chunk.js} +0 -0
  52. /package/lib/{index-DTDXUe6m.d.ts → index2.d.ts} +0 -0
  53. /package/lib/{kernel-env-x_WkG6Fr.js → kernel-env2.js} +0 -0
  54. /package/lib/{lib-C8_jXvwA.js → lib.js} +0 -0
  55. /package/lib/{lsp-server-registry-D4VLs1Sm.js → lsp-server-registry.js} +0 -0
  56. /package/lib/{native-capture-BEByDXYM.js → native-capture.js} +0 -0
  57. /package/lib/{py-sdk-D7klhpWb.js → py-sdk2.js} +0 -0
  58. /package/lib/{util-BHL_dfV_.js → util.js} +0 -0
  59. /package/lib/{web-tree-sitter-CPrPD4J2.js → web-tree-sitter.js} +0 -0
  60. /package/lib/{wrap-0VA0uFx8.js → wrap.js} +0 -0
@@ -1,15 +1,15 @@
1
- import { t as Schema } from "../lib-C8_jXvwA.js";
1
+ import { t as Schema } from "../lib.js";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
3
  import { createHash, randomBytes, randomUUID } from "node:crypto";
4
- import { constants, createReadStream, createWriteStream, mkdirSync, readFileSync, statSync } from "node:fs";
4
+ import { constants, createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
5
5
  import { dirname, isAbsolute, join, posix, resolve } from "node:path";
6
6
  import { spawn } from "node:child_process";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { homedir, tmpdir } from "node:os";
9
9
  import { defineTool } from "@deepseek-ai/dsh-tools";
10
10
  import { chmod, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, rename, rm, stat, symlink, writeFile } from "node:fs/promises";
11
- import { pipeline } from "node:stream/promises";
12
11
  import { Readable } from "node:stream";
12
+ import { pipeline } from "node:stream/promises";
13
13
  import { createConnection, createServer } from "node:net";
14
14
 
15
15
  //#region src/remote/archive.ts
@@ -318,17 +318,18 @@ async function copyTree(request, source, destination, signal, scratchRoot = join
318
318
  signal.throwIfAborted();
319
319
  if (request.argv !== void 0 || request.pullArgv !== void 0 || request.pushArgv !== void 0) throw new Error("copy: argv/pullArgv/pushArgv are native CLI options; the Hub/local staged lane does not accept CLI options");
320
320
  await mkdir(scratchRoot, { recursive: true });
321
- signal.throwIfAborted();
322
- const scratch = await mkdtemp(join(scratchRoot, "remote-copy-")), payload = join(scratch, "payload.bin");
323
321
  const receipt = {
324
322
  action: "copy",
323
+ route: "hub-staged",
325
324
  src: request.src,
326
325
  dst: request.dst,
327
- verified: false,
326
+ ok: false,
327
+ verification: "not-applicable",
328
328
  bytes: 0,
329
329
  entries: 0,
330
330
  scope: "transferred entries"
331
331
  };
332
+ const scratch = await mkdtemp(join(scratchRoot, "remote-copy-")), payload = join(scratch, "payload.bin");
332
333
  try {
333
334
  await pipeline(await source.endpoint.exportTree(source.path, signal), createWriteStream(payload, {
334
335
  flags: "wx",
@@ -352,24 +353,79 @@ async function copyTree(request, source, destination, signal, scratchRoot = join
352
353
  const dest = await destination.endpoint.digest(destination.path, signal, selection);
353
354
  receipt.destinationDigest = dest.sha256;
354
355
  if (dest.sha256 !== receipt.sourceDigest) throw new Error("destination digest mismatch");
355
- receipt.verified = true;
356
+ receipt.verification = "sha256";
356
357
  }
357
358
  signal.throwIfAborted();
358
359
  await rm(scratch, {
359
360
  recursive: true,
360
361
  force: true
361
362
  });
363
+ receipt.ok = true;
362
364
  return receipt;
363
365
  } catch (error) {
366
+ const message = error instanceof Error ? error.message : String(error);
367
+ const reason = signal.aborted ? "aborted" : /mismatch/i.test(message) ? "digest-mismatch" : "staging-error";
364
368
  throw new CopyError({
365
369
  ...receipt,
366
- verified: false,
370
+ ok: false,
371
+ reason,
367
372
  scratch,
368
- error: error instanceof Error ? error.message : String(error)
373
+ error: message
369
374
  });
370
375
  }
371
376
  }
372
377
 
378
+ //#endregion
379
+ //#region src/remote/ssh-argv.ts
380
+ /**
381
+ * ONE identity-assembly policy for every SSH-speaking lane (user close-out
382
+ * ruling 2026-10-17: "four builders necessarily mean four identity
383
+ * semantics" — the structural root of F1).
384
+ *
385
+ * Assembly: explicit connection fields (byossh registrations; caller options
386
+ * may override later by the CLI's own last-option-wins) in ONE order —
387
+ * user, port, key, proxyJump — spoken in the target CLI's dialect.
388
+ *
389
+ * Resolution: config-side identity (aliases, config-only IdentityFile paths)
390
+ * is read from the ORIGIN's own ssh config natively by every lane. The single
391
+ * exception is the scp -3 temp config (ssh -F sees no user config), where
392
+ * tempSshConfig inlines the `ssh -G`-resolved fields — paths only, never key
393
+ * material (F1, 2026-10-14). That policy lives beside this builder in
394
+ * native-copy.ts and must stay the only such inline site.
395
+ *
396
+ * Former duplicate builders now reduced here: sshArgv (execution/probes),
397
+ * identityArgv (scp routes), rsyncRsh (RSYNC_RSH wiring), relaySsh
398
+ * (dual-SSH relay). Behavior is byte-identical to each former site.
399
+ */
400
+ /** Identity options ONLY for one connection, in the target CLI's dialect:
401
+ * user, port, key, proxyJump — conditional, one order, NO base flags (each
402
+ * lane's dialect base — BatchMode, -T, hardening — stays at its call site).
403
+ * scp carries the user inside its user@host operand, so the scp dialect
404
+ * never emits -l; its port flag is -P. */
405
+ function sshIdentityArgv(connection, dialect) {
406
+ const args = [];
407
+ if (dialect === "ssh" && connection.user !== void 0) args.push("-l", connection.user);
408
+ if (connection.port !== void 0) args.push(dialect === "scp" ? "-P" : "-p", String(connection.port));
409
+ if (connection.key !== void 0) args.push("-i", connection.key);
410
+ if (connection.proxyJump !== void 0) args.push("-J", connection.proxyJump);
411
+ return args;
412
+ }
413
+ /** Full ssh invocation around the shared identity core. base and extra are
414
+ * trusted internal argv (dialect flags incl. BatchMode, forwarding options)
415
+ * — never a model-provided shell string. */
416
+ function sshCommandArgv(connection, base, extra, command) {
417
+ const args = [
418
+ "ssh",
419
+ ...base,
420
+ ...sshIdentityArgv(connection, "ssh"),
421
+ ...extra,
422
+ "--",
423
+ connection.host
424
+ ];
425
+ if (command !== void 0) args.push(command);
426
+ return args;
427
+ }
428
+
373
429
  //#endregion
374
430
  //#region src/remote/output-ring.ts
375
431
  const continuation = (byte) => (byte & 192) === 128;
@@ -675,15 +731,17 @@ function scpSpec(connection, path$1) {
675
731
  const host = connection.host.includes(":") ? `[${connection.host}]` : connection.host;
676
732
  return `${connection.user !== void 0 ? `${connection.user}@${host}` : host}:${path$1}`;
677
733
  }
678
- /** Connection identity as scp options (port, key), placed BEFORE caller argv so
679
- * an explicit caller -F/-i/-P/-J overrides the registered identity by scp's own
680
- * precedence (last option wins). */
734
+ /** Connection identity as scp options, placed BEFORE caller argv so an
735
+ * explicit caller -F/-i/-P/-J overrides the registered identity by scp's own
736
+ * precedence (last option wins). Assembly itself lives in ssh-argv.ts
737
+ * (the ONE identity policy — 2026-10-17 ruling); only the scp dialect
738
+ * placement rule is local. */
681
739
  function identityArgv(connection) {
682
- const options = ["-o", "BatchMode=yes"];
683
- if (connection.port !== void 0) options.push("-P", String(connection.port));
684
- if (connection.key !== void 0) options.push("-i", connection.key);
685
- if (connection.proxyJump !== void 0) options.push("-J", connection.proxyJump);
686
- return options;
740
+ return [
741
+ "-o",
742
+ "BatchMode=yes",
743
+ ...sshIdentityArgv(connection, "scp")
744
+ ];
687
745
  }
688
746
  function sshEndpoint(plan) {
689
747
  if (plan.kind !== "ssh") throw new Error("remote: native copy endpoint is not an SSH target");
@@ -722,18 +780,23 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
722
780
  stdout: [],
723
781
  stderr: [],
724
782
  outputTruncated: false,
725
- verified: false,
783
+ verification: "native-exit-only",
784
+ ok: true,
726
785
  cleanup: "none-required"
727
786
  };
728
- const finish = (route, argvs, results) => {
787
+ const finish = (route, argvs, results, internal = []) => {
729
788
  receipt.route = route;
730
- receipt.argv = argvs;
789
+ receipt.argv = argvs.map((argv) => argv.map((token) => internal.find(([secret]) => secret === token)?.[1] ?? token));
731
790
  receipt.exits = results.map((result) => result.exit);
732
791
  receipt.stdout = results.map((result) => result.stdout);
733
792
  receipt.stderr = results.map((result) => result.stderr);
734
793
  receipt.outputTruncated = results.some((result) => result.outputTruncated);
794
+ receipt.ok = !signal.aborted && receipt.exits.every((exit) => exit === 0);
795
+ if (!receipt.ok) receipt.reason = signal.aborted ? "aborted" : "non-zero-exit";
735
796
  return receipt;
736
797
  };
798
+ if (request.mkdir !== false) await ensureDestinationDir(endpoints.dst, signal, options.execArgvFor, wrap, receipt);
799
+ else receipt.created = "n-a";
737
800
  if (s === "local" && t === "ssh") {
738
801
  rejectRemoteToRemoteScp(oneShot);
739
802
  const connection = sshEndpoint(endpoints.dst.plan).connection;
@@ -786,7 +849,7 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
786
849
  srcSpec,
787
850
  dstSpec
788
851
  ];
789
- return finish("scp -3 (data through origin)", [argv], [await runNative(wrap(argv), signal)]);
852
+ return finish("scp-3", [argv], [await runNative(wrap(argv), signal)], config !== void 0 ? [[config.path, "<temp-ssh-config>"]] : []);
790
853
  } catch (error) {
791
854
  if (signal.aborted) unknown = true;
792
855
  throw error;
@@ -807,7 +870,7 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
807
870
  ];
808
871
  const result = await runNative(wrap(argv), signal);
809
872
  withSymlinkHint(result);
810
- return finish("docker cp", [argv], [result]);
873
+ return finish("docker-cp", [argv], [result]);
811
874
  }
812
875
  if (s === "docker" && t === "local") {
813
876
  const argv = [
@@ -819,7 +882,7 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
819
882
  ];
820
883
  const result = await runNative(wrap(argv), signal);
821
884
  withSymlinkHint(result);
822
- return finish("docker cp", [argv], [result]);
885
+ return finish("docker-cp", [argv], [result]);
823
886
  }
824
887
  if (s === "local" && t === "incus") {
825
888
  const argv = [
@@ -831,7 +894,7 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
831
894
  endpoints.src.path,
832
895
  `${containerOf(endpoints.dst.plan)}${endpoints.dst.path}`
833
896
  ];
834
- return finish("incus file push", [argv], [await runNative(wrap(argv), signal)]);
897
+ return finish("incus-file-push", [argv], [await runNative(wrap(argv), signal)]);
835
898
  }
836
899
  if (s === "incus" && t === "local") {
837
900
  const argv = [
@@ -842,7 +905,7 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
842
905
  `${containerOf(endpoints.src.plan)}${endpoints.src.path}`,
843
906
  endpoints.dst.path
844
907
  ];
845
- return finish("incus file pull", [argv], [await runNative(wrap(argv), signal)]);
908
+ return finish("incus-file-pull", [argv], [await runNative(wrap(argv), signal)]);
846
909
  }
847
910
  if (s === "local" || t === "local") throw new Error("remote: this endpoint pair is a single native command route; pullArgv/pushArgv apply to cross-endpoint pairs only");
848
911
  const pullOptions = request.pullArgv !== void 0 ? pull : oneShot;
@@ -855,9 +918,12 @@ async function nativeCopy(request, endpoints, signal, options = {}) {
855
918
  const pullArgv = segmentArgv(endpoints.src.plan, endpoints.src.path, staged, pullOptions, "pull");
856
919
  const pushArgv = segmentArgv(endpoints.dst.plan, endpoints.dst.path, staged, pushOptions, "push");
857
920
  const first = await runNative(wrap(pullArgv), signal);
858
- if (first.exit !== 0) return finish("two native commands with origin staging (push not started: pull failed)", [pullArgv], [first]);
921
+ if (first.exit !== 0) {
922
+ receipt.note = "push not started: pull failed";
923
+ return finish("staged-pull-push", [pullArgv], [first], [[staged, "<staging>"]]);
924
+ }
859
925
  const second = await runNative(wrap(pushArgv), signal);
860
- return finish("two native commands with origin staging", [pullArgv, pushArgv], [first, second]);
926
+ return finish("staged-pull-push", [pullArgv, pushArgv], [first, second], [[staged, "<staging>"]]);
861
927
  } finally {
862
928
  receipt.cleanup = await rm(scratch, {
863
929
  recursive: true,
@@ -918,6 +984,58 @@ function segmentArgv(plan, remote, staged, opts, leg) {
918
984
  spec
919
985
  ];
920
986
  }
987
+ /** D3 mkdir pre-hop: ensure the destination's PARENT directory exists before
988
+ * the transfer (never the operand itself — see parent-only note below).
989
+ * transfer. Local dst is node-side; remote dst runs ONE exec `mkdir -p` probe
990
+ * whose stdout discloses created-vs-existed. Best-effort by contract: any
991
+ * failure records created:'n-a' + note and lets the copy proceed so the native
992
+ * CLI surfaces the real error (and stopped-container docker cp keeps working). */
993
+ async function ensureDestinationDir(dst, signal, execArgvFor, wrap, receipt) {
994
+ const dir = dirname(dst.path);
995
+ if (dir === "/" || dir === ".") {
996
+ receipt.created = false;
997
+ return;
998
+ }
999
+ if (dst.plan.kind === "local") {
1000
+ try {
1001
+ if (existsSync(dir)) {
1002
+ receipt.created = false;
1003
+ return;
1004
+ }
1005
+ mkdirSync(dir, { recursive: true });
1006
+ receipt.created = true;
1007
+ } catch (error) {
1008
+ receipt.created = "n-a";
1009
+ receipt.note = `mkdir pre-hop failed: ${error instanceof Error ? error.message : String(error)}`;
1010
+ }
1011
+ return;
1012
+ }
1013
+ if (execArgvFor === void 0) {
1014
+ receipt.created = "n-a";
1015
+ return;
1016
+ }
1017
+ if (/[\r\n]/.test(dir)) {
1018
+ receipt.created = "n-a";
1019
+ receipt.note = "mkdir pre-hop skipped: newline-bearing destination path";
1020
+ return;
1021
+ }
1022
+ const quoted = `'${dir.replaceAll("'", "'\\\\''")}'`;
1023
+ const script = `if [ -d ${quoted} ]; then echo existed; else mkdir -p ${quoted} && echo created; fi`;
1024
+ try {
1025
+ const result = await runNative(wrap(execArgvFor(dst.plan, script)), signal);
1026
+ const word = result.stdout.trim().split("\n").pop();
1027
+ if (result.exit === 0 && word === "created") receipt.created = true;
1028
+ else if (result.exit === 0 && word === "existed") receipt.created = false;
1029
+ else {
1030
+ receipt.created = "n-a";
1031
+ const tail = result.stderr.trim().split("\n").filter((line) => line.length > 0).pop();
1032
+ receipt.note = `mkdir pre-hop unavailable (exit ${result.exit})${tail !== void 0 ? `: ${tail}` : ""}`;
1033
+ }
1034
+ } catch (error) {
1035
+ receipt.created = "n-a";
1036
+ receipt.note = `mkdir pre-hop failed: ${error instanceof Error ? error.message : String(error)}`;
1037
+ }
1038
+ }
921
1039
  /** Distinguishing identities for scp -3: an origin-only temp config maps two
922
1040
  * synthetic aliases; keys are referenced in place, never copied to any remote. */
923
1041
  /** D8 (2026-10-14 user adoption, third acceptance round): a LOCAL directory source gets
@@ -1018,10 +1136,10 @@ async function resolveThroughOriginConfig(c, runNative$1) {
1018
1136
  //#endregion
1019
1137
  //#region src/remote/ssh-rsync-native-relay.ts
1020
1138
  /** ssh argv for the relay: batch, no agent, no multiplexing. `command` is the
1021
- * remote command; forwarding options go before `--`, the host after it. */
1139
+ * remote command; forwarding options go before `--`, the host after it.
1140
+ * Identity core comes from ssh-argv.ts (the ONE policy — 2026-10-17 ruling). */
1022
1141
  function relaySsh(connection, extra, command) {
1023
- const args = [
1024
- "ssh",
1142
+ return sshCommandArgv(connection, [
1025
1143
  "-o",
1026
1144
  "BatchMode=yes",
1027
1145
  "-T",
@@ -1038,14 +1156,7 @@ function relaySsh(connection, extra, command) {
1038
1156
  "ServerAliveInterval=5",
1039
1157
  "-o",
1040
1158
  "ServerAliveCountMax=2"
1041
- ];
1042
- if (connection.user !== void 0) args.push("-l", connection.user);
1043
- if (connection.port !== void 0) args.push("-p", String(connection.port));
1044
- if (connection.key !== void 0) args.push("-i", connection.key);
1045
- if (connection.proxyJump !== void 0) args.push("-J", connection.proxyJump);
1046
- args.push(...extra, "--", connection.host);
1047
- if (command !== void 0) args.push(command);
1048
- return args;
1159
+ ], extra, command);
1049
1160
  }
1050
1161
  async function freePorts(count) {
1051
1162
  const servers = [];
@@ -1328,14 +1439,7 @@ async function runRsync(request, source, destination, signal, options = {}) {
1328
1439
  checkAbsolute(destination.path);
1329
1440
  const argv = checkArgv("argv", request.argv);
1330
1441
  if ("pullArgv" in request || "pushArgv" in request) throw new Error("remote: rsync takes argv only; pullArgv/pushArgv are copy-only fields");
1331
- for (const legacy of [
1332
- "dryRun",
1333
- "delete",
1334
- "excludes",
1335
- "preserve",
1336
- "verify",
1337
- "mkdir"
1338
- ]) if (legacy in request) throw new Error(`remote: rsync field "${legacy}" was removed — pass native options through argv instead (e.g. "--dry-run", "--delete", "--exclude=<pattern>", "-a"/"-r"; verify/mkdir belong to the copy Hub/local lane)`);
1442
+ for (const key of Object.keys(request)) if (key !== "src" && key !== "dst" && key !== "argv") throw new Error(`remote: rsync rejects unknown field "${key}" — native options go through argv (verify is a copy Hub-lane option; mkdir is copy-only; for destination parents pass --mkpath yourself)`);
1339
1443
  if (!source.connection && !destination.connection) throw new Error("rsync requires at least one SSH endpoint; local-only is unsupported");
1340
1444
  let result;
1341
1445
  let route;
@@ -1383,6 +1487,9 @@ async function runRsync(request, source, destination, signal, options = {}) {
1383
1487
  dst: request.dst,
1384
1488
  argv,
1385
1489
  route,
1490
+ verification: "native-exit-only",
1491
+ ok: result.exit === 0,
1492
+ ...result.exit === 0 ? {} : { reason: signal.aborted ? "aborted" : "non-zero-exit" },
1386
1493
  command: `rsync ${argv.join(" ")}`,
1387
1494
  ...itemized.length > 0 || argv.includes("--itemize-changes") || argv.includes("-i") ? { itemizedChanges: itemized } : {},
1388
1495
  ...literalBytes === void 0 ? {} : { literalBytes },
@@ -1397,21 +1504,14 @@ async function runRsync(request, source, destination, signal, options = {}) {
1397
1504
  * placeholder host rsync appends and execs the canonical SSH argv. All tokens
1398
1505
  * are tool-built argv (identity options/aliases), never model text. */
1399
1506
  function rsyncRsh(connection, wrap) {
1400
- const args = [
1401
- "ssh",
1402
- "-o",
1403
- "BatchMode=yes",
1404
- "-T"
1405
- ];
1406
- if (connection.user !== void 0) args.push("-l", connection.user);
1407
- if (connection.port !== void 0) args.push("-p", String(connection.port));
1408
- if (connection.key !== void 0) args.push("-i", connection.key);
1409
- if (connection.proxyJump !== void 0) args.push("-J", connection.proxyJump);
1410
- args.push("--", connection.host);
1411
1507
  return [
1412
1508
  "bash",
1413
1509
  "-c",
1414
- `shift; exec ${wrap(args).map(rshQuote).join(" ")} "$@"`,
1510
+ `shift; exec ${wrap(sshCommandArgv(connection, [
1511
+ "-o",
1512
+ "BatchMode=yes",
1513
+ "-T"
1514
+ ], [])).map(rshQuote).join(" ")} "$@"`,
1415
1515
  "rsync-rsh"
1416
1516
  ].map(rshQuote).join(" ");
1417
1517
  }
@@ -1507,26 +1607,19 @@ var SshTargets = class {
1507
1607
  }
1508
1608
  };
1509
1609
  /** Shared by execution, probes and file/relay consumers. extraArgs is trusted
1510
- * internal SSH argv (e.g. forwarding), never a model-provided shell string. */
1610
+ * internal SSH argv (e.g. forwarding), never a model-provided shell string.
1611
+ * Identity assembly lives in ssh-argv.ts (the ONE policy — 2026-10-17 ruling);
1612
+ * this wrapper only picks the tty/batch dialect base. */
1511
1613
  function sshArgv(connection, options = {}) {
1512
- const args = options.tty ? [
1513
- "ssh",
1614
+ return sshCommandArgv(connection, options.tty ? [
1514
1615
  "-tt",
1515
1616
  "-o",
1516
1617
  "BatchMode=yes"
1517
1618
  ] : [
1518
- "ssh",
1519
1619
  "-o",
1520
1620
  "BatchMode=yes",
1521
1621
  "-T"
1522
- ];
1523
- if (connection.user !== void 0) args.push("-l", connection.user);
1524
- if (connection.port !== void 0) args.push("-p", String(connection.port));
1525
- if (connection.key !== void 0) args.push("-i", connection.key);
1526
- if (connection.proxyJump !== void 0) args.push("-J", connection.proxyJump);
1527
- args.push(...options.extraArgs ?? [], "--", connection.host);
1528
- if (options.command !== void 0) args.push(options.command);
1529
- return args;
1622
+ ], options.extraArgs ?? [], options.command);
1530
1623
  }
1531
1624
 
1532
1625
  //#endregion
@@ -2688,13 +2781,18 @@ var RemoteDriver = class {
2688
2781
  path: dst.path,
2689
2782
  endpoint: localFileEndpoint()
2690
2783
  }, combined);
2691
- if (request.verify !== void 0 || request.mkdir !== void 0) throw new Error("copy: verify/mkdir apply to the Hub/local staged lane only; native CLI routes do not verify or create parents (mirror the CLI's own behavior with argv like -r)");
2784
+ if (request.verify !== void 0) throw new Error("copy: verify is a Hub/local staged lane option (independent SHA-256); native routes report exit-code-only verification — self-verify via oneshot digest commands when needed");
2692
2785
  const planOf = (end) => end.kind === "cli" ? end.plan : end.kind === "local" ? { kind: "local" } : void 0;
2693
2786
  const srcPlan = planOf(src), dstPlan = planOf(dst);
2694
2787
  if (srcPlan === void 0 || dstPlan === void 0) throw new Error("copy: unreachable route resolution");
2788
+ const execArgvFor = (plan, script) => {
2789
+ const argv = helperShellArgv(plan, script);
2790
+ return this.opts.nativeArgvFor ? this.opts.nativeArgvFor(argv) : argv;
2791
+ };
2695
2792
  return nativeCopy({
2696
2793
  src: request.src,
2697
2794
  dst: request.dst,
2795
+ ...request.mkdir === void 0 ? {} : { mkdir: request.mkdir },
2698
2796
  ...request.argv === void 0 ? {} : { argv: request.argv },
2699
2797
  ...request.pullArgv === void 0 ? {} : { pullArgv: request.pullArgv },
2700
2798
  ...request.pushArgv === void 0 ? {} : { pushArgv: request.pushArgv }
@@ -2707,7 +2805,10 @@ var RemoteDriver = class {
2707
2805
  plan: dstPlan,
2708
2806
  path: dst.path
2709
2807
  }
2710
- }, combined, { wrapArgv: this.opts.nativeArgvFor });
2808
+ }, combined, {
2809
+ wrapArgv: this.opts.nativeArgvFor,
2810
+ execArgvFor
2811
+ });
2711
2812
  })();
2712
2813
  this.starting.add(work);
2713
2814
  work.then(() => this.starting.delete(work), () => this.starting.delete(work));
@@ -3286,7 +3387,7 @@ Bare names resolve ssh config → docker → incus → live pty; unmatched goes
3286
3387
 
3287
3388
  oneshot: stateless bash -lc, stdout/stderr separate, exit code verbatim. Supervision prefers a pinned superd-run helper cached on the endpoint (~/.cache/superd/run; first call uploads it over the same exec lane) and falls back to a POSIX wrapper everywhere else — the result field "runner" says which ran. Helper or wrapper, backgrounded children are reaped on completion and the whole group is killed on timeout/cancel; the endpoint needs bash only (no Python).
3288
3389
 
3289
- Files — {action:"copy" | "rsync", src:"[target:]abs", dst:"[target:]abs", argv:["-a"]}: argv tokens pass verbatim before src/dst — no whitelist, no forced defaults (dry run = pass "--dry-run" yourself); the CLI's own exit code and stderr come back in the receipt. copy: local↔SSH scp; SSH↔SSH scp -3 through the origin (identities stay local); docker cp; incus file push/pull; any other pair = two commands with origin staging (per-half options via pullArgv/pushArgv, exclusive with argv); scp -R (uppercase — scp's remote-client mode) is refused; copy of a directory from a LOCAL source auto-appends the route's recursive flag (-r, shown in the receipt argv); from a REMOTE source pass -r yourself or use rsync; success is NOT independently verified; verify/mkdir only on the Hub↔local lane. rsync: local↔SSH, or SSH↔SSH with one protocol conversation between the peers (real delta; forwarding denied → honest error, never full copy). rsync src trailing slash copies contents, no slash the directory itself.
3390
+ Files — {action:"copy" | "rsync", src:"[target:]abs", dst:"[target:]abs", argv:["-a"]}: argv tokens pass verbatim before src/dst — no whitelist, no forced defaults (dry run = pass "--dry-run" yourself); the CLI's own exit code and stderr come back in the receipt. copy: local↔SSH scp; SSH↔SSH scp -3 through the origin (identities stay local); docker cp; incus file push/pull; any other pair = two commands with origin staging (per-half options via pullArgv/pushArgv, exclusive with argv); scp -R (uppercase — scp's remote-client mode) is refused; copy of a directory from a LOCAL source auto-appends the route's recursive flag (-r, shown in the receipt argv); from a REMOTE source pass -r yourself or use rsync; mkdir defaults to ensuring the destination's PARENT directory first (one exec pre-hop, outcome in the receipt created field; the operand itself is never pre-created); receipts use stable route ids (scp / scp-3 / docker-cp / incus-file-push / incus-file-pull / staged-pull-push / hub-staged) with ok+reason, the verification tier actually performed (native-exit-only by default; sha256 on the Hub lane) and tool-owned temp paths in argv shown as placeholders. rsync: local↔SSH, or SSH↔SSH with one protocol conversation between the peers (real delta; forwarding denied → honest error, never full copy). rsync src trailing slash copies contents, no slash the directory itself.
3290
3391
 
3291
3392
  Output: pty tails at ~30k chars ("[truncated: …]" header) — redirect bulk output to a file. Hard retention 4,000,000 UTF-16 units per stream (Hub 4MiB bytes); outputStats reports the rest; restart cannot recover discarded output. stdin feeds the command; timeout (seconds) interrupts then kills. run_in_background:true (oneshot) → jobId for job_output/job_kill. Native transport errors pass through verbatim — self-correct from them.`;
3292
3393
  function createRemoteTool(driver, opts = {}) {
@@ -3325,11 +3426,11 @@ function createRemoteTool(driver, opts = {}) {
3325
3426
  },
3326
3427
  verify: {
3327
3428
  type: "boolean",
3328
- description: "copy only, Hub↔local↔local staged lane only: independent SHA-256 verification (default true). Native CLI routes do not verify and report that fact."
3429
+ description: "copy only. Receipts name the verification tier actually performed (D1=A): native CLI routes are \"native-exit-only\" (no independent check — self-verify via oneshot digest commands when needed); the Hub↔local staged lane computes independent SHA-256 digests by default and verify:false skips them (\"not-applicable\"). No hash tier exists on native routes."
3329
3430
  },
3330
3431
  mkdir: {
3331
3432
  type: "boolean",
3332
- description: "copy only, Hub↔local↔local staged lane only: create missing destination parents (default true). Native CLI routes let the CLI decide."
3433
+ description: "copy only, all routes. Default true: before transfer, one best-effort exec pre-hop ensures the destination's PARENT directory exists (the operand itself is never pre-created — each CLI's own layout semantics stay byte-identical). Receipt created field: true (parent created this call) / false (already existed) / \"n-a\" (skipped or pre-hop unavailable, e.g. docker exec on a stopped container — the native CLI then reports the real error itself). false skips the pre-hop."
3333
3434
  },
3334
3435
  run_in_background: {
3335
3436
  type: "boolean",
@@ -3452,12 +3553,26 @@ function createRemoteTool(driver, opts = {}) {
3452
3553
  args.timeout,
3453
3554
  args.run_in_background
3454
3555
  ].some((value) => value !== void 0)) throw new Error(`${args.action} cannot be combined with execution/PTY/job arguments; register byossh separately first`);
3455
- for (const legacy of [
3456
- "dryRun",
3457
- "delete",
3458
- "excludes",
3459
- "preserve"
3460
- ]) if (args[legacy] !== void 0) throw new Error(`${legacy} was removed: pass native options through argv instead (e.g. ${legacy === "dryRun" ? "\"--dry-run\"" : legacy === "delete" ? "\"--delete\"" : legacy === "excludes" ? "\"--exclude=<pattern>\"" : "\"-a\" / \"-r\""})`);
3556
+ const KNOWN_PARAMS = new Set([
3557
+ "action",
3558
+ "src",
3559
+ "dst",
3560
+ "argv",
3561
+ "pullArgv",
3562
+ "pushArgv",
3563
+ "verify",
3564
+ "mkdir",
3565
+ "run_in_background",
3566
+ "target",
3567
+ "ssh",
3568
+ "spawn",
3569
+ "cmd",
3570
+ "script",
3571
+ "mode",
3572
+ "stdin",
3573
+ "timeout"
3574
+ ]);
3575
+ for (const key of Object.keys(args)) if (!KNOWN_PARAMS.has(key)) throw new Error(`remote: unknown parameter "${key}" — this surface has no legacy aliases (dryRun/delete/excludes/preserve are gone); pass native CLI options through argv instead`);
3461
3576
  if (args.action === "rsync") {
3462
3577
  if (args.pullArgv !== void 0 || args.pushArgv !== void 0) throw new Error("rsync takes argv only; pullArgv/pushArgv are copy-only fields");
3463
3578
  if ([args.verify, args.mkdir].some((value) => value !== void 0)) throw new Error("rsync cannot be combined with copy verify/mkdir options; the Hub/local staged lane is copy-only");
@@ -3467,13 +3582,14 @@ function createRemoteTool(driver, opts = {}) {
3467
3582
  dst: args.dst,
3468
3583
  ...args.argv === void 0 ? {} : { argv: args.argv }
3469
3584
  }, exec.signal, { sessionKey: getSessionKey(exec) });
3470
- if (receipt$1.exit !== 0) throw new Error(JSON.stringify(receipt$1));
3585
+ if (receipt$1.ok === false || receipt$1.exit !== 0) throw new Error(JSON.stringify(receipt$1));
3586
+ const rsyncDuration = Date.now() - start;
3471
3587
  return {
3472
3588
  kind: "rsync",
3473
- text: JSON.stringify(receipt$1),
3589
+ text: formatTransferLine("rsync", receipt$1, rsyncDuration),
3474
3590
  receipt: receipt$1,
3475
3591
  exit: receipt$1.exit,
3476
- durationMs: Date.now() - start
3592
+ durationMs: rsyncDuration
3477
3593
  };
3478
3594
  }
3479
3595
  const copyStart = Date.now();
@@ -3486,14 +3602,16 @@ function createRemoteTool(driver, opts = {}) {
3486
3602
  ...args.pullArgv === void 0 ? {} : { pullArgv: args.pullArgv },
3487
3603
  ...args.pushArgv === void 0 ? {} : { pushArgv: args.pushArgv }
3488
3604
  }, exec.signal, { sessionKey: getSessionKey(exec) });
3489
- const exits = receipt.exits ?? [];
3490
- if (exits.some((code) => code !== 0)) throw new Error(JSON.stringify(receipt));
3605
+ const asReceipt = receipt;
3606
+ const exits = asReceipt.exits ?? [];
3607
+ if (asReceipt.ok === false || exits.some((code) => code !== 0)) throw new Error(JSON.stringify(receipt));
3608
+ const copyDuration = Date.now() - copyStart;
3491
3609
  return {
3492
3610
  kind: "copy",
3493
- text: JSON.stringify(receipt),
3611
+ text: formatTransferLine("copy", receipt, copyDuration),
3494
3612
  receipt,
3495
3613
  exit: exits.length > 0 ? 0 : null,
3496
- durationMs: Date.now() - copyStart
3614
+ durationMs: copyDuration
3497
3615
  };
3498
3616
  }
3499
3617
  if ([
@@ -3590,6 +3708,26 @@ function createRemoteTool(driver, opts = {}) {
3590
3708
  });
3591
3709
  return tool;
3592
3710
  }
3711
+ /** S8 (2026-10-17): copy/rsync render as one formatted line; the full receipt
3712
+ * stays in the receipt field — raw-JSON dumps are gone from text. */
3713
+ function formatTransferLine(action, receipt, durationMs) {
3714
+ const r = receipt;
3715
+ const parts = [];
3716
+ if (r.ok === false) parts.push(`✗ ${r.reason ?? "failed"}`);
3717
+ parts.push(`${action} ${r.src} → ${r.dst}`);
3718
+ if (r.route !== void 0 && r.route !== "") parts.push(`route ${r.route}`);
3719
+ if (r.exits !== void 0) parts.push(`exits [${r.exits.join(",")}]`);
3720
+ else if (r.exit !== void 0) parts.push(`exit ${r.exit}`);
3721
+ if (r.verification !== void 0) parts.push(`verification ${r.verification}`);
3722
+ if (r.created === true) parts.push("created yes");
3723
+ else if (r.created === false) parts.push("created pre-existing");
3724
+ else if (r.created === "n-a") parts.push("created n-a");
3725
+ if (r.cleanup !== void 0 && r.cleanup !== "none-required") parts.push(`cleanup ${r.cleanup}`);
3726
+ if (typeof r.bytes === "number") parts.push(`${r.bytes} bytes / ${r.entries} entries`);
3727
+ parts.push(`${(durationMs / 1e3).toFixed(1)}s`);
3728
+ if (r.note !== void 0 && r.note.length > 0) parts.push(`(${r.note})`);
3729
+ return parts.join(" · ");
3730
+ }
3593
3731
  function renderValue(v) {
3594
3732
  if (v.kind === "status" || v.kind === "roster" || v.kind === "job" || v.kind === "copy" || v.kind === "rsync") return v.text;
3595
3733
  const parts = [];
@@ -1,4 +1,4 @@
1
- import { t as Schema } from "../index-DTDXUe6m.js";
1
+ import { t as Schema } from "../index2.js";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
3
  import { ToolDefinition } from "@deepseek-ai/dsh-tools";
4
4
 
@@ -1,10 +1,10 @@
1
- import { r as __toESM, t as __commonJS } from "../chunk-DQxbwPpZ.js";
2
- import { t as Schema } from "../lib-C8_jXvwA.js";
3
- import { t as PACKAGE_ROOT } from "../kernel-env-x_WkG6Fr.js";
4
- import { n as captureNativeTools } from "../native-capture-BEByDXYM.js";
5
- import { a as createHttpHandler, c as listDvcDevices, d as UrlResolver, f as UrlSchemesError, h as SCHEME_NAMES, i as HTTP_SCHEMES, l as registerDvcDevice, m as parseUrl, n as wrapFsWithSchemes, o as createDvcHandler, p as applySelector, r as resolveDocsDir, s as dispatchDvcWrite, u as createDshHandler } from "../wrap-0VA0uFx8.js";
6
- import { n as Parser } from "../web-tree-sitter-CPrPD4J2.js";
7
- import { a as primaryServerForFile, c as serversForFile, n as findWorkspaceRoot, o as resolveCommandPath, r as installHintFor, s as serverByName } from "../lsp-server-registry-D4VLs1Sm.js";
1
+ import { r as __toESM, t as __commonJS } from "../chunk.js";
2
+ import { t as Schema } from "../lib.js";
3
+ import { t as PACKAGE_ROOT } from "../kernel-env2.js";
4
+ import { n as captureNativeTools } from "../native-capture.js";
5
+ import { a as createHttpHandler, c as listDvcDevices, d as UrlResolver, f as UrlSchemesError, h as SCHEME_NAMES, i as HTTP_SCHEMES, l as registerDvcDevice, m as parseUrl, n as wrapFsWithSchemes, o as createDvcHandler, p as applySelector, r as resolveDocsDir, s as dispatchDvcWrite, u as createDshHandler } from "../wrap.js";
6
+ import { n as Parser } from "../web-tree-sitter.js";
7
+ import { a as primaryServerForFile, c as serversForFile, n as findWorkspaceRoot, o as resolveCommandPath, r as installHintFor, s as serverByName } from "../lsp-server-registry.js";
8
8
  import { createRequire } from "node:module";
9
9
  import { createHash, randomUUID } from "node:crypto";
10
10
  import { accessSync, constants, existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
@@ -133,7 +133,7 @@ function astEngine() {
133
133
  return enginePromise;
134
134
  }
135
135
  async function boot() {
136
- const bg = await import("../wasm_bg-CNXhHjVg.js");
136
+ const bg = await import("../wasm_bg.js");
137
137
  const bytes = await readAsset(ASTGREP_WASM.file);
138
138
  const { instance } = await WebAssemblyGlobal.instantiate(bytes, { "./wasm_bg.js": bg });
139
139
  bg.__wbg_set_wasm(instance.exports);
@@ -1435,7 +1435,7 @@ const PUPPETEER_CORE_VERSION = "25.3.0";
1435
1435
  */
1436
1436
  async function loadPuppeteer() {
1437
1437
  if (puppeteerModule === void 0) try {
1438
- puppeteerModule = await import("../puppeteer-core-C-4NyOpY.js");
1438
+ puppeteerModule = await import("../puppeteer-core.js");
1439
1439
  } catch {
1440
1440
  try {
1441
1441
  puppeteerModule = await import(pathToFileURL((await ensureVendored({
@@ -2500,7 +2500,7 @@ function ensureMustHave(gate, language) {
2500
2500
  if (!MUST_HAVE.has(language) || gate.installTried.has(language)) return;
2501
2501
  gate.installTried.add(language);
2502
2502
  (async () => {
2503
- const registry = await import("../lsp-server-registry-BcdkHROD.js");
2503
+ const registry = await import("../lsp-server-registry2.js");
2504
2504
  const probePath = `/tmp/x.${language === "python" ? "py" : "ts"}`;
2505
2505
  const primary = registry.primaryServerForFile(probePath);
2506
2506
  if (primary === null) return;
@@ -3189,7 +3189,7 @@ async function lspDeviceRead(subpath, session) {
3189
3189
  if (parsed === void 0) return `unknown read path dvc://lsp/${subpath} — reads: status | diagnostics?file=…[&all=1] | definition?file=&line=[&character=|&symbol=] | references?… | hover?…`;
3190
3190
  if (parsed.action === "status") {
3191
3191
  const availability = {};
3192
- const registry = await import("../lsp-server-registry-BcdkHROD.js");
3192
+ const registry = await import("../lsp-server-registry2.js");
3193
3193
  for (const language of [
3194
3194
  "python",
3195
3195
  "typescript",
@@ -1,4 +1,4 @@
1
- import { n as Parser, t as Language } from "./web-tree-sitter-CPrPD4J2.js";
1
+ import { n as Parser, t as Language } from "./web-tree-sitter.js";
2
2
 
3
3
  //#region node_modules/@ast-grep/wasm/wasm_bg.js
4
4
  var Pos = class Pos {
@@ -1,4 +1,4 @@
1
- import { t as Schema } from "./index-DTDXUe6m.js";
1
+ import { t as Schema } from "./index2.js";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
3
  import { IncomingMessage } from "node:http";
4
4
  import { CredentialRecord } from "@deepseek-ai/dsh-credentials";
@@ -1,4 +1,4 @@
1
- import { t as Schema } from "./lib-C8_jXvwA.js";
1
+ import { t as Schema } from "./lib.js";
2
2
  import { createHash, createHmac, randomBytes, scrypt, timingSafeEqual } from "node:crypto";
3
3
  import { readFile } from "node:fs/promises";
4
4
  import { credentialKey } from "@deepseek-ai/dsh-credentials";
@@ -1,3 +1,3 @@
1
- import "./index-DTDXUe6m.js";
2
- import { a as _default, c as buildTrustScript, d as name, i as TrustConfig, l as deriveDefaultPageAuthorities, n as Config, o as apply, r as MobileConfig, s as buildMobileScript, t as BootScriptRow, u as inject } from "./web-trust-Dej_RI2B.js";
1
+ import "./index2.js";
2
+ import { a as _default, c as buildTrustScript, d as name, i as TrustConfig, l as deriveDefaultPageAuthorities, n as Config, o as apply, r as MobileConfig, s as buildMobileScript, t as BootScriptRow, u as inject } from "./web-trust2.js";
3
3
  export { BootScriptRow, Config, MobileConfig, TrustConfig, apply, buildMobileScript, buildTrustScript, _default as default, deriveDefaultPageAuthorities, inject, name };