dsh-plugin-wsl-env 0.7.5 → 0.9.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 (92) hide show
  1. package/CHANGELOG.md +345 -8
  2. package/CONTRIBUTING.md +221 -68
  3. package/README.md +50 -35
  4. package/SECURITY.md +18 -2
  5. package/SUPPORT.md +23 -7
  6. package/cordis.patch.yml +9 -0
  7. package/docs/ARCHITECTURE.md +200 -57
  8. package/docs/CONFIGURATION.md +180 -16
  9. package/docs/LIMITATIONS.md +91 -33
  10. package/docs/PARITY.md +66 -38
  11. package/docs/PEER-PARITY.md +95 -32
  12. package/docs/README.zh.md +49 -31
  13. package/docs/UPSTREAM-FSIO-EXPORT.md +159 -50
  14. package/docs/UPSTREAM-TERMINAL-TITLE.md +49 -14
  15. package/lib/agent-confined.d.ts +42 -0
  16. package/lib/agent-confined.js +25 -41
  17. package/lib/agent-errors.d.ts +31 -0
  18. package/lib/agent-errors.js +19 -16
  19. package/lib/agent-exec.d.ts +159 -0
  20. package/lib/agent-exec.js +151 -165
  21. package/lib/agent-protocol.d.ts +192 -0
  22. package/lib/agent-protocol.js +76 -100
  23. package/lib/agent-shared.d.ts +27 -0
  24. package/lib/agent-shared.js +12 -12
  25. package/lib/agent.d.ts +353 -0
  26. package/lib/agent.js +536 -552
  27. package/lib/auto-preset.d.ts +110 -0
  28. package/lib/auto-preset.js +157 -141
  29. package/lib/bwrap.d.ts +90 -0
  30. package/lib/bwrap.js +18 -18
  31. package/lib/file-reference-wsl.d.ts +160 -0
  32. package/lib/file-reference-wsl.js +192 -173
  33. package/lib/fs-decisions.d.ts +107 -0
  34. package/lib/fs-decisions.js +64 -60
  35. package/lib/fs-routing.d.ts +182 -0
  36. package/lib/fs-routing.js +173 -116
  37. package/lib/fs-substrate.d.ts +258 -0
  38. package/lib/fs-substrate.js +248 -248
  39. package/lib/fs.d.ts +10 -0
  40. package/lib/fs.js +5 -0
  41. package/lib/fsio-agent.d.ts +307 -0
  42. package/lib/fsio-agent.js +414 -410
  43. package/lib/fsio-text.d.ts +115 -0
  44. package/lib/fsio-text.js +104 -84
  45. package/lib/git-route.d.ts +100 -0
  46. package/lib/git-route.js +46 -47
  47. package/lib/index.d.ts +1003 -0
  48. package/lib/index.js +1106 -1003
  49. package/lib/listing.d.ts +114 -0
  50. package/lib/listing.js +68 -55
  51. package/lib/paths.d.ts +182 -0
  52. package/lib/paths.js +134 -109
  53. package/lib/picker.d.ts +266 -0
  54. package/lib/picker.js +371 -351
  55. package/lib/ports.d.ts +44 -0
  56. package/lib/ports.js +39 -29
  57. package/lib/preflight.d.ts +91 -0
  58. package/lib/preflight.js +94 -0
  59. package/lib/preset-choice.d.ts +33 -0
  60. package/lib/preset-choice.js +15 -7
  61. package/lib/probe-cache.d.ts +51 -0
  62. package/lib/probe-cache.js +43 -29
  63. package/lib/sandbox-core.d.ts +149 -0
  64. package/lib/sandbox-core.js +239 -87
  65. package/lib/sandbox.d.ts +48 -0
  66. package/lib/sandbox.js +4 -4
  67. package/lib/search-exec.d.ts +96 -0
  68. package/lib/search-exec.js +52 -79
  69. package/lib/search-route.d.ts +75 -0
  70. package/lib/search-route.js +30 -31
  71. package/lib/shell-env.d.ts +88 -0
  72. package/lib/shell-env.js +78 -74
  73. package/lib/shell.d.ts +10 -0
  74. package/lib/shell.js +5 -0
  75. package/lib/subprocess.d.ts +313 -0
  76. package/lib/subprocess.js +267 -262
  77. package/lib/terminal-activity.d.ts +98 -0
  78. package/lib/terminal-activity.js +29 -39
  79. package/lib/terminal-route.d.ts +27 -0
  80. package/lib/terminal-route.js +16 -8
  81. package/lib/watcher.d.ts +77 -0
  82. package/lib/watcher.js +120 -126
  83. package/lib/workspace-files-route.d.ts +132 -0
  84. package/lib/workspace-files-route.js +73 -81
  85. package/lib/workspace-files-wsl.d.ts +257 -0
  86. package/lib/workspace-files-wsl.js +311 -251
  87. package/lib/wsl.d.ts +266 -0
  88. package/lib/wsl.js +150 -155
  89. package/locale/preflight/en.json +6 -0
  90. package/locale/preflight/zh.json +6 -0
  91. package/package.json +78 -22
  92. package/scripts/diagnose.sh +92 -0
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The filesystem provider's POLICY DECISIONS, extracted from
3
+ * `lib/index.js` so they are unit-testable in a bare checkout: which paths are
4
+ * refused for naming another distro, which mode refuses a mutation outright,
5
+ * which write guards refuse which intents, and how a substrate failure maps
6
+ * onto the refusal the tool layer surfaces. Pure in, descriptor out — no I/O,
7
+ * no peers (the provider wraps these descriptors in `FsError` at one choke
8
+ * point, keeping the peer import out of this module and the decisions honest).
9
+ *
10
+ * Every message here is model-facing and must stay byte-identical to what the
11
+ * provider produced before the extraction — the tool layer and the model match
12
+ * on these strings.
13
+ *
14
+ * This is a TypeScript source built to `lib/fs-decisions.js`; edit THIS file
15
+ * and run `pnpm run build` — the artifact under `lib/` is generated, and
16
+ * `pnpm test` fails when it drifts.
17
+ *
18
+ * @module dsh-plugin-wsl/fs-decisions
19
+ */
20
+ /** A refusal descriptor the provider wraps in `FsError` at one choke point. */
21
+ export interface Refusal {
22
+ /** The model-facing refusal text. */
23
+ message: string;
24
+ /** The `FS_*` token. */
25
+ code: string;
26
+ }
27
+ /**
28
+ * The worldPath decision: a path that resolves into another WSL distro is
29
+ * refused while `restrictToDistro` holds — deliberately NOT a sandbox denial,
30
+ * because no wider permission can lift a configuration choice.
31
+ *
32
+ * @param input - the decision's inputs.
33
+ * @returns the refusal, or null to proceed.
34
+ */
35
+ export declare function outsideDistroRefusal({ path, world, distro, restrictToDistro }: {
36
+ path: string;
37
+ world: string;
38
+ distro: string;
39
+ restrictToDistro: boolean;
40
+ }): Refusal | null;
41
+ /**
42
+ * The mutationAgent decision: does THIS mutation route to the confined
43
+ * resident? An absent policy (caller pre-checked), a disabled sandbox, and an
44
+ * approved escalation all address the plain resident — which is what those
45
+ * mean.
46
+ *
47
+ * @param input - the decision's inputs.
48
+ * @returns true when the mutation belongs to the confined resident.
49
+ */
50
+ export declare function isConfinedMutation({ policy, sandboxEnabled }: {
51
+ policy: {
52
+ mode: string;
53
+ workspaceRoot: string;
54
+ } | undefined;
55
+ sandboxEnabled: boolean;
56
+ }): boolean;
57
+ /**
58
+ * The mode-level mutation decision: `read-only` refuses every write outright;
59
+ * `danger-full-access` is the approved escalation and refuses nothing.
60
+ * `workspace-write` refuses nothing HERE — its containment check needs the
61
+ * fresh target and runs in the provider.
62
+ *
63
+ * @param mode - the resolved policy mode.
64
+ * @param displayPath - the caller-facing path for the message.
65
+ * @returns the refusal, or null to proceed.
66
+ */
67
+ export declare function mutationModeRefusal(mode: string, displayPath: string): Refusal | null;
68
+ /**
69
+ * The containment denial for a `workspace-write` mutation whose fresh target
70
+ * sat under no writable root.
71
+ *
72
+ * @param displayPath - the caller-facing path for the message.
73
+ * @returns the refusal descriptor.
74
+ */
75
+ export declare function workspaceWriteDenial(displayPath: string): Refusal;
76
+ /**
77
+ * The substrate configuration decision: the Windows-side share no longer
78
+ * serves the file tools. Every distro read and write runs on the resident
79
+ * agent, so no model-facing I/O crosses the 9p share at all — the share
80
+ * backend it replaces was the one path that still could. The provider throws
81
+ * this at construction time, before any session forms, so a profile carrying
82
+ * the old value fails loudly with the migration instead of silently serving
83
+ * I/O the configuration did not mean to allow.
84
+ *
85
+ * @param substrate - the configured substrate value; absent on a
86
+ * direct construction, which is not the retired share.
87
+ * @returns the refusal, or null to proceed.
88
+ */
89
+ export declare function shareSubstrateRefusal(substrate?: string): {
90
+ message: string;
91
+ } | null;
92
+ /**
93
+ * The substrate failure mapping: what the tool layer should surface for an
94
+ * error that crossed the `ctx.fs` seam. A coded refusal keeps its code and
95
+ * message byte-for-byte; anything else is the substrate being UNAVAILABLE —
96
+ * the resident agent that serves every distro read and write is out — and the
97
+ * message names the recovery path, because there is no fallback I/O for it to
98
+ * point at.
99
+ *
100
+ * @param error - what the substrate raised.
101
+ * @returns the refusal the provider wraps in `FsError`.
102
+ */
103
+ export declare function substrateFailure(error: unknown): {
104
+ message: string;
105
+ code: string;
106
+ cause: unknown;
107
+ };
@@ -11,73 +11,72 @@
11
11
  * provider produced before the extraction — the tool layer and the model match
12
12
  * on these strings.
13
13
  *
14
+ * This is a TypeScript source built to `lib/fs-decisions.js`; edit THIS file
15
+ * and run `pnpm run build` — the artifact under `lib/` is generated, and
16
+ * `pnpm test` fails when it drifts.
17
+ *
14
18
  * @module dsh-plugin-wsl/fs-decisions
15
19
  */
16
-
17
20
  import { isAnotherDistrosUnc } from "./paths.js";
18
-
19
- /** A refusal descriptor the provider wraps in `FsError` at one choke point. */
21
+ /**
22
+ * Build one refusal descriptor.
23
+ *
24
+ * @param message - the model-facing refusal text.
25
+ * @param code - the `FS_*` token.
26
+ * @returns the descriptor.
27
+ */
20
28
  const refusal = (message, code) => ({ message, code });
21
-
22
29
  /**
23
30
  * The worldPath decision: a path that resolves into another WSL distro is
24
31
  * refused while `restrictToDistro` holds — deliberately NOT a sandbox denial,
25
32
  * because no wider permission can lift a configuration choice.
26
- * @param {object} input - the decision's inputs.
27
- * @param {string} input.path - the path as the caller spelled it.
28
- * @param {string} input.world - the resolved world path (a UNC for distro paths).
29
- * @param {string} input.distro - the pinned distro name.
30
- * @param {boolean} input.restrictToDistro - the configuration fence.
31
- * @returns {{message: string, code: string}|null} the refusal, or null to proceed.
33
+ *
34
+ * @param input - the decision's inputs.
35
+ * @returns the refusal, or null to proceed.
32
36
  */
33
37
  export function outsideDistroRefusal({ path, world, distro, restrictToDistro }) {
34
- if (!restrictToDistro || !isAnotherDistrosUnc(world, distro)) return null;
35
- return refusal(
36
- `"${path}" names a path in another WSL distro, and this profile pins its filesystem to "${distro}" ` +
37
- `(restrictToDistro: true). Open a session in that distro, or set restrictToDistro: false.`,
38
- "FS_OUTSIDE_DISTRO",
39
- );
38
+ if (!restrictToDistro || !isAnotherDistrosUnc(world, distro))
39
+ return null;
40
+ return refusal(`"${path}" names a path in another WSL distro, and this profile pins its filesystem to "${distro}" ` +
41
+ `(restrictToDistro: true). Open a session in that distro, or set restrictToDistro: false.`, "FS_OUTSIDE_DISTRO");
40
42
  }
41
-
42
43
  /**
43
44
  * The mutationAgent decision: does THIS mutation route to the confined
44
45
  * resident? An absent policy (caller pre-checked), a disabled sandbox, and an
45
46
  * approved escalation all address the plain resident — which is what those
46
47
  * mean.
47
- * @param {object} input - the decision's inputs.
48
- * @param {{mode: string, workspaceRoot: string}|undefined} input.policy - the
49
- * resolved file-effect policy.
50
- * @param {boolean} input.sandboxEnabled - the provider's `sandbox` configuration.
51
- * @returns {boolean} true when the mutation belongs to the confined resident.
48
+ *
49
+ * @param input - the decision's inputs.
50
+ * @returns true when the mutation belongs to the confined resident.
52
51
  */
53
52
  export function isConfinedMutation({ policy, sandboxEnabled }) {
54
- return Boolean(policy) && Boolean(sandboxEnabled) && policy.mode !== "danger-full-access";
53
+ return policy !== undefined && Boolean(sandboxEnabled) && policy.mode !== "danger-full-access";
55
54
  }
56
-
57
55
  /**
58
56
  * The mode-level mutation decision: `read-only` refuses every write outright;
59
57
  * `danger-full-access` is the approved escalation and refuses nothing.
60
58
  * `workspace-write` refuses nothing HERE — its containment check needs the
61
59
  * fresh target and runs in the provider.
62
- * @param {string} mode - the resolved policy mode.
63
- * @param {string} displayPath - the caller-facing path for the message.
64
- * @returns {{message: string, code: string}|null} the refusal, or null to proceed.
60
+ *
61
+ * @param mode - the resolved policy mode.
62
+ * @param displayPath - the caller-facing path for the message.
63
+ * @returns the refusal, or null to proceed.
65
64
  */
66
65
  export function mutationModeRefusal(mode, displayPath) {
67
- if (mode !== "read-only") return null;
68
- return refusal(`cannot write "${displayPath}": file access denied under read-only mode`, "FS_SANDBOX_DENIED");
66
+ if (mode !== "read-only")
67
+ return null;
68
+ return refusal(`cannot write "${displayPath}": file access denied under read-only mode`, "FS_SANDBOX_DENIED");
69
69
  }
70
-
71
70
  /**
72
71
  * The containment denial for a `workspace-write` mutation whose fresh target
73
72
  * sat under no writable root.
74
- * @param {string} displayPath - the caller-facing path for the message.
75
- * @returns {{message: string, code: string}} the refusal descriptor.
73
+ *
74
+ * @param displayPath - the caller-facing path for the message.
75
+ * @returns the refusal descriptor.
76
76
  */
77
77
  export function workspaceWriteDenial(displayPath) {
78
- return refusal(`cannot write "${displayPath}": file access denied under workspace-write mode`, "FS_SANDBOX_DENIED");
78
+ return refusal(`cannot write "${displayPath}": file access denied under workspace-write mode`, "FS_SANDBOX_DENIED");
79
79
  }
80
-
81
80
  /**
82
81
  * The substrate configuration decision: the Windows-side share no longer
83
82
  * serves the file tools. Every distro read and write runs on the resident
@@ -86,19 +85,20 @@ export function workspaceWriteDenial(displayPath) {
86
85
  * this at construction time, before any session forms, so a profile carrying
87
86
  * the old value fails loudly with the migration instead of silently serving
88
87
  * I/O the configuration did not mean to allow.
89
- * @param {string} substrate - the configured substrate value.
90
- * @returns {{message: string}|null} the refusal, or null to proceed.
88
+ *
89
+ * @param substrate - the configured substrate value; absent on a
90
+ * direct construction, which is not the retired share.
91
+ * @returns the refusal, or null to proceed.
91
92
  */
92
93
  export function shareSubstrateRefusal(substrate) {
93
- if (substrate !== "share") return null;
94
- return {
95
- message:
96
- 'wsl-fs: substrate "share" is no longer available — the resident agent serves every ' +
97
- "distro read and write, and no file tool crosses the 9p share. Delete the substrate " +
98
- 'line from the provider config, or set it to "agent".',
99
- };
94
+ if (substrate !== "share")
95
+ return null;
96
+ return {
97
+ message: 'wsl-fs: substrate "share" is no longer available — the resident agent serves every ' +
98
+ "distro read and write, and no file tool crosses the 9p share. Delete the substrate " +
99
+ 'line from the provider config, or set it to "agent".',
100
+ };
100
101
  }
101
-
102
102
  /**
103
103
  * The substrate failure mapping: what the tool layer should surface for an
104
104
  * error that crossed the `ctx.fs` seam. A coded refusal keeps its code and
@@ -106,24 +106,28 @@ export function shareSubstrateRefusal(substrate) {
106
106
  * the resident agent that serves every distro read and write is out — and the
107
107
  * message names the recovery path, because there is no fallback I/O for it to
108
108
  * point at.
109
- * @param {unknown} error - what the substrate raised.
110
- * @returns {{message: string, code: string, cause: unknown}} the refusal the
111
- * provider wraps in `FsError`.
109
+ *
110
+ * @param error - what the substrate raised.
111
+ * @returns the refusal the provider wraps in `FsError`.
112
112
  */
113
113
  export function substrateFailure(error) {
114
- if (isCoded(error)) return { message: error.message, code: error.code, cause: error };
115
- const message = error instanceof Error ? error.message : String(error);
116
- return {
117
- message:
118
- `the distro file substrate is unavailable: ${message}. ` +
119
- `The resident agent serves every distro read and write; check the distro is running ` +
120
- `("wsl.exe -l -v") and restart the session if it stays out.`,
121
- code: "FS_IO_ERROR",
122
- cause: error instanceof Error ? error : undefined,
123
- };
114
+ if (isCoded(error))
115
+ return { message: error.message, code: error.code, cause: error };
116
+ const message = error instanceof Error ? error.message : String(error);
117
+ return {
118
+ message: `the distro file substrate is unavailable: ${message}. ` +
119
+ `The resident agent serves every distro read and write; check the distro is running ` +
120
+ `("wsl.exe -l -v") and restart the session if it stays out.`,
121
+ code: "FS_IO_ERROR",
122
+ cause: error instanceof Error ? error : undefined,
123
+ };
124
124
  }
125
-
126
- /** A coded refusal: our `FsCodedError` duck (a message, a string `FS_*` code). */
125
+ /**
126
+ * A coded refusal: our `FsCodedError` duck (a message, a string `FS_*` code).
127
+ *
128
+ * @param error - what the substrate raised.
129
+ * @returns true when `error` carries a string `FS_*` code.
130
+ */
127
131
  function isCoded(error) {
128
- return error instanceof Error && typeof error.code === "string" && error.code.startsWith("FS_");
132
+ return error instanceof Error && typeof error.code === "string" && error.code.startsWith("FS_");
129
133
  }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * The root-plane filesystem with coordinate routing: targets under a
3
+ * `\\wsl.localhost\<distro>` identity are served by the distro substrate
4
+ * (the resident agent, on ext4); every other target — drive-letter paths,
5
+ * the deployment cwd — is served by the host `LocalFileSystem` this class
6
+ * extends, unchanged.
7
+ *
8
+ * ## Why a router, and why here
9
+ *
10
+ * The root `ctx.fs` is session-less: it cannot be switched per session the
11
+ * way a preset's isolated `fs` can, so the two workspace kinds share one
12
+ * backend — and the stock backend serves the distro workspace across the 9p
13
+ * share, in its slow direction, with no usable change notifications. Routing
14
+ * by coordinate makes every root consumer (the workspace-files change feed
15
+ * among them) correct on both workspace kinds without per-consumer patches.
16
+ *
17
+ * The design note is `docs/root-fs-routing.md` (the operation routing table,
18
+ * the intended behavior differences, and the dormant-root-fence rationale).
19
+ *
20
+ * ## What is intentionally not here
21
+ *
22
+ * No write fence: the root plane has no write consumers (the model's writes
23
+ * ride the per-session preset filesystems, which enforce their own
24
+ * containment — the distro side kernel-enforced). If a root-plane write
25
+ * consumer appears, its fence rides with that consumer.
26
+ *
27
+ * This is a TypeScript source built to `lib/fs-routing.js`; edit THIS file and
28
+ * run `pnpm run build` — the artifact under `lib/` is generated, and `pnpm test`
29
+ * fails when it drifts.
30
+ *
31
+ * @module dsh-plugin-wsl/fs-routing
32
+ */
33
+ import { LocalFileSystem } from "@deepseek-ai/dsh-fs-local";
34
+ import { WslFileSystem } from "./index.js";
35
+ import type { Context } from "@deepseek-ai/cordis";
36
+ import type { FsTarget, FsVersion, FsWriteIntent, FsEditRequest } from "@deepseek-ai/dsh-fs";
37
+ import type { SandboxExecutionPolicy } from "@deepseek-ai/dsh-sandbox";
38
+ /**
39
+ * The router's config: the host backend's own knobs plus the distro knobs the
40
+ * routed backend reads. The distro keys are `??`-defaulted, so a host-only
41
+ * config stays valid.
42
+ */
43
+ export interface RoutingConfig {
44
+ /** The host backend's base directory. */
45
+ cwd?: string;
46
+ /** The host backend's overwrite-diff byte bound. */
47
+ diffBasisMaxBytes?: number;
48
+ /** The pinned distro for routed targets; empty resolves WSL's default. */
49
+ distro?: string;
50
+ /** The `wsl.exe` path, used only to resolve the default distro. */
51
+ wslPath?: string;
52
+ /** The routed backend's default workdir. */
53
+ distroCwd?: string;
54
+ /** Whether the routed backend fences mutations by `ctx.sandboxPolicy`. */
55
+ sandbox?: boolean;
56
+ /** Whether confined profiles shadow `/mnt`. */
57
+ maskWindowsDrive?: boolean;
58
+ /** Whether the routed backend refuses paths outside the distro. */
59
+ restrictToDistro?: boolean;
60
+ /** How deep the in-distro watch scan walks. */
61
+ watchMaxDepth?: number;
62
+ }
63
+ /**
64
+ * Whether a resolved target identity belongs to the distro.
65
+ *
66
+ * @param targetKey - the target's identity (a UNC for distro paths).
67
+ * @returns true when the target lives inside a WSL distro.
68
+ */
69
+ export declare function targetIsDistro(targetKey: string): boolean;
70
+ /**
71
+ * Whether a raw path-or-cwd input names the distro (used by the operations
72
+ * that take paths before a target exists: resolve, lstat).
73
+ *
74
+ * @param value - a path in any coordinate system, or undefined.
75
+ * @returns true when the input names a distro UNC.
76
+ */
77
+ export declare function inputIsDistro(value: string | undefined): boolean;
78
+ /**
79
+ * The root-plane filesystem with coordinate routing.
80
+ *
81
+ * The distro backend is built lazily on the first routed target, sharing this
82
+ * context (the root `sandboxPolicy` service provides the deployment default
83
+ * mode the distro side reports through `sandboxMode`).
84
+ */
85
+ export declare class WslRoutingFileSystem extends LocalFileSystem {
86
+ #private;
87
+ static Config: import("@deepseek-ai/schemastery").default<import("@deepseek-ai/dsh-fs-local").Config>;
88
+ /**
89
+ * @param ctx - the cordis context.
90
+ * @param config - the row config, host knobs plus distro knobs.
91
+ */
92
+ constructor(ctx: Context, config: RoutingConfig);
93
+ /** The distro backend for routed targets, built on first use. */
94
+ distro(): WslFileSystem;
95
+ /**
96
+ * @param path - the requested path.
97
+ * @param opts - the resolve options.
98
+ */
99
+ resolve(path: string, opts?: {
100
+ cwd?: string;
101
+ signal?: AbortSignal;
102
+ }): Promise<FsTarget>;
103
+ /**
104
+ * @param path - the requested path.
105
+ * @param opts - the lstat options.
106
+ * @param signal - cancels the round trip.
107
+ */
108
+ lstat(path: string, opts?: {
109
+ cwd?: string;
110
+ }, signal?: AbortSignal): Promise<import("@deepseek-ai/dsh-fs").FsPathInfo | undefined>;
111
+ /**
112
+ * @param target - the resolved target.
113
+ * @param signal - cancels the round trip.
114
+ */
115
+ stat(target: FsTarget, signal?: AbortSignal): Promise<import("@deepseek-ai/dsh-fs").FsInfo | undefined>;
116
+ /**
117
+ * @param target - the resolved target.
118
+ * @param signal - cancels the round trip.
119
+ */
120
+ readText(target: FsTarget, signal?: AbortSignal): Promise<string>;
121
+ /**
122
+ * @param target - the resolved target.
123
+ * @param signal - cancels the stream.
124
+ */
125
+ streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>;
126
+ /**
127
+ * @param target - the resolved target.
128
+ * @param signal - cancels the read.
129
+ * @param maxBytes - the inclusive byte cap.
130
+ */
131
+ readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array<ArrayBufferLike>>;
132
+ /**
133
+ * @param target - the resolved target.
134
+ * @param range - the byte window.
135
+ * @param signal - cancels the read.
136
+ */
137
+ readByteRange(target: FsTarget, range: {
138
+ offset: number;
139
+ length: number;
140
+ }, signal?: AbortSignal): Promise<Uint8Array<ArrayBufferLike>>;
141
+ /**
142
+ * @param target - the resolved directory.
143
+ * @param signal - cancels the listing.
144
+ */
145
+ listDir(target: FsTarget, signal?: AbortSignal): Promise<import("@deepseek-ai/dsh-fs").FsDirEntry[]>;
146
+ /**
147
+ * @param target - the resolved target.
148
+ * @param content - the full new content.
149
+ * @param expected - the guarded-write intent.
150
+ * @param signal - cancels the write.
151
+ * @param sandboxPolicy - the confined policy the distro side honors; the
152
+ * host backend takes no such parameter.
153
+ */
154
+ writeText(target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy): Promise<import("@deepseek-ai/dsh-fs").FsWriteOutcome>;
155
+ /**
156
+ * @param target - the resolved target.
157
+ * @param edit - the literal edit.
158
+ * @param expected - the version the edit was based on.
159
+ * @param signal - cancels the edit.
160
+ * @param sandboxPolicy - the confined policy the distro side honors; the
161
+ * host backend takes no such parameter.
162
+ */
163
+ editText(target: FsTarget, edit: FsEditRequest, expected?: {
164
+ version: FsVersion;
165
+ }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy): Promise<import("@deepseek-ai/dsh-fs").FsEditOutcome>;
166
+ /**
167
+ * @param target - the resolved target.
168
+ * @param changed - the change callback.
169
+ * @param signal - cancels the watch.
170
+ */
171
+ watch(target: FsTarget, changed: (error?: Error) => void, signal: AbortSignal): Promise<() => Promise<void>>;
172
+ /**
173
+ * @param parent - the container.
174
+ * @param child - the contained candidate.
175
+ */
176
+ contains(parent: FsTarget, child: FsTarget): boolean;
177
+ /**
178
+ * @param target - the resolved target.
179
+ */
180
+ processPath(target: FsTarget): string;
181
+ }
182
+ export default WslRoutingFileSystem;