@dsh-electron/dsh-plugin-multi-root-workspace 0.1.6 → 0.1.8
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.
- package/CHANGELOG.en.md +51 -1
- package/CHANGELOG.md +51 -1
- package/README.en.md +155 -92
- package/README.md +156 -91
- package/cordis.patch.yml +69 -4
- package/lib/client.js +2678 -276
- package/lib/client.js.map +1 -1
- package/lib/command-CESuwlVt.js +1306 -0
- package/lib/command.js +2 -2
- package/lib/compat-DR2LvmYZ.js +600 -0
- package/lib/compat.js +1 -1
- package/lib/contract-DZ4zczDT.js +238 -0
- package/lib/{fs-D_Sw3o5z.js → fs-Nlp2AiRX.js} +56 -24
- package/lib/fs.js +2 -1
- package/lib/index.js +10 -8
- package/lib/{instructions-DfzN-wVf.js → instructions-D19jRxN0.js} +3 -2
- package/lib/instructions.js +1 -1
- package/lib/lsp.js +7 -2
- package/lib/method-wrapper-CFY3p3j2.js +26 -0
- package/lib/process-fence.js +280 -0
- package/lib/providers.js +87 -0
- package/lib/{registry-DySMbjgW.js → registry-DCxC5Lay.js} +256 -35
- package/lib/registry.js +2 -2
- package/lib/{roots-DasWEBJk.js → roots-B-0l8mNG.js} +117 -20
- package/lib/sandbox-CVAcT_gy.js +743 -0
- package/lib/sandbox.js +2 -1
- package/lib/scope.js +229 -20
- package/lib/types/client/RootSwitcher.d.ts +63 -0
- package/lib/types/client/WorkspaceFoldersAction.d.ts +39 -1
- package/lib/types/client/files-tree/FilesBody.module.css.d.ts +24 -0
- package/lib/types/client/files-tree/FilesTree.d.ts +47 -0
- package/lib/types/client/files-tree/adapter.d.ts +94 -0
- package/lib/types/client/files-tree/directory-node.d.ts +62 -0
- package/lib/types/client/files-tree/face.d.ts +107 -0
- package/lib/types/client/files-tree/locales.d.ts +10 -0
- package/lib/types/client/files-tree/primitives.d.ts +33 -0
- package/lib/types/client/files-tree/store.d.ts +81 -0
- package/lib/types/client/locales.d.ts +56 -10
- package/lib/types/client/open-in-app/OpenInAppAction.d.ts +27 -0
- package/lib/types/client/open-in-app/OpenTargetButton.d.ts +52 -0
- package/lib/types/client/open-in-app/OpenTargetButton.module.css.d.ts +29 -0
- package/lib/types/client/open-in-app/adapter.d.ts +46 -0
- package/lib/types/client/open-in-app/applications.d.ts +4 -0
- package/lib/types/client/open-in-app/controller.d.ts +53 -0
- package/lib/types/client/open-in-app/locales.d.ts +10 -0
- package/lib/types/client/open-in-app/open-failure-toast.d.ts +11 -0
- package/lib/types/client/open-in-app/open-path.d.ts +13 -0
- package/lib/types/client/panel-client.d.ts +2 -1
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/command.d.ts +16 -3
- package/lib/types/compat/client-icons.d.ts +18 -0
- package/lib/types/compat/dsh-version.d.ts +57 -9
- package/lib/types/compat/open-in-app-routes.d.ts +38 -0
- package/lib/types/compat/process-entrypoints.d.ts +31 -0
- package/lib/types/compat/process-result.d.ts +14 -0
- package/lib/types/compat/pty-marker.d.ts +83 -0
- package/lib/types/compat/sandbox-confine.d.ts +2 -0
- package/lib/types/compat/storage-zod.d.ts +65 -0
- package/lib/types/compat/windows-deny-preflight.d.ts +21 -0
- package/lib/types/compat/windows-native.d.ts +68 -0
- package/lib/types/compat/windows-path-guard.d.ts +56 -0
- package/lib/types/compat/workspace-files.d.ts +2 -0
- package/lib/types/compat.d.ts +15 -5
- package/lib/types/contract.d.ts +31 -19
- package/lib/types/dialects.d.ts +99 -3
- package/lib/types/fs.d.ts +32 -10
- package/lib/types/index.d.ts +8 -3
- package/lib/types/process-fence.d.ts +54 -0
- package/lib/types/profile-isolation.d.ts +178 -0
- package/lib/types/providers.d.ts +70 -0
- package/lib/types/registry.d.ts +132 -31
- package/lib/types/roots.d.ts +100 -13
- package/lib/types/sandbox.d.ts +59 -3
- package/lib/types/scope.d.ts +200 -14
- package/lib/types/windows-broker.d.ts +17 -0
- package/lib/types/windows-deny.d.ts +1 -0
- package/lib/types/windows-profile.d.ts +10 -13
- package/lib/types/windows-runner-contract.d.ts +97 -0
- package/lib/windows-runner-contract-CEfmZzu0.js +141 -0
- package/lib/windows-runner.js +1256 -13
- package/lib/workspace-files.js +138 -3
- package/lib/workspace-routing-YPxaQ4V3.js +26 -0
- package/package.json +84 -62
- package/scripts/windows-broker/install.ps1 +89 -0
- package/scripts/windows-broker/rights.cs +58 -0
- package/scripts/windows-broker/service.cs +323 -0
- package/scripts/windows-broker/verify-install.ps1 +80 -0
- package/lib/command-CTdNvwt1.js +0 -791
- package/lib/compat-B6ZqbQBy.js +0 -295
- package/lib/method-wrapper-Zc-JlDP3.js +0 -51
- package/lib/sandbox-BRXl_FpF.js +0 -132
- package/lib/types/client/RootFileTree.d.ts +0 -12
- package/lib/types/panel-files.d.ts +0 -3
- package/lib/windows-profile-CiFsFYIV.js +0 -216
- package/lib/{registry-lease-win32-dy8TQMD9.js → registry-lease-win32-DTO6QpT9.js} +2 -2
package/lib/compat-B6ZqbQBy.js
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
import { Service } from "@deepseek-ai/cordis";
|
|
3
|
-
//#region src/compat/dsh-version.ts
|
|
4
|
-
/**
|
|
5
|
-
* The DSH compatibility contract: which upstream releases this plugin is
|
|
6
|
-
* actually verified against, and how an installation is judged against that
|
|
7
|
-
* list.
|
|
8
|
-
*
|
|
9
|
-
* This module is the ONE place the support matrix is spelled out. It is
|
|
10
|
-
* deliberately pure — no cordis, no logging, no process exit — so that the
|
|
11
|
-
* runtime gate (`src/compat.ts`), the static gate (`scripts/check-dsh-compat.mjs`)
|
|
12
|
-
* and the tests all judge an installation by the same code instead of three
|
|
13
|
-
* drifting copies of the same list.
|
|
14
|
-
*
|
|
15
|
-
* Why a contract exists at all: this plugin replaces `ctx.fs` and `ctx.sandbox`
|
|
16
|
-
* with subclasses of the upstream providers, and `src/dialects.ts` recognizes
|
|
17
|
-
* the kernel-sandbox profile by OBSERVING the argv shape `super.confine`
|
|
18
|
-
* produced (ADR-0003). Both couplings are to pre-stable upstream internals that
|
|
19
|
-
* carry no semver promise. An npm range like `>=0.1.2-alpha.4 <0.2.0` therefore
|
|
20
|
-
* promises far more than the code was ever verified against; the allowlist
|
|
21
|
-
* below promises exactly what CI has run.
|
|
22
|
-
*
|
|
23
|
-
* @module @dsh-electron/dsh-plugin-multi-root-workspace/compat/dsh-version
|
|
24
|
-
*/
|
|
25
|
-
/**
|
|
26
|
-
* The releases this plugin is verified against, as EXACT version strings.
|
|
27
|
-
*
|
|
28
|
-
* Not a semver range, on purpose: a range is a prediction about releases that
|
|
29
|
-
* do not exist yet, and this plugin's coupling to upstream argv shapes makes
|
|
30
|
-
* that prediction unsafe. Adding an entry is always a human act performed after
|
|
31
|
-
* the upgrade smoke passed on that exact version — a green CI run on an
|
|
32
|
-
* unlisted release is evidence, not authorization (ADR-0009).
|
|
33
|
-
*/
|
|
34
|
-
const SUPPORTED_DSH_RELEASES = [
|
|
35
|
-
"0.1.5-rc.2",
|
|
36
|
-
"0.1.6-alpha.1",
|
|
37
|
-
"0.1.6-alpha.2",
|
|
38
|
-
"0.1.7-alpha.1",
|
|
39
|
-
"0.1.7-alpha.2",
|
|
40
|
-
"0.1.7-rc.1",
|
|
41
|
-
"0.1.7-rc.2",
|
|
42
|
-
"0.2.0-rc.1",
|
|
43
|
-
"0.2.0-rc.2",
|
|
44
|
-
"0.2.1-alpha.1",
|
|
45
|
-
"0.2.1-alpha.2"
|
|
46
|
-
];
|
|
47
|
-
/**
|
|
48
|
-
* Packages whose absence means this plugin cannot function at all: every one of
|
|
49
|
-
* them is either subclassed, imported for a value, or the owner of a service
|
|
50
|
-
* key the providers inject.
|
|
51
|
-
*/
|
|
52
|
-
const REQUIRED_CORE_PACKAGES = [
|
|
53
|
-
"@deepseek-ai/dsh-fs",
|
|
54
|
-
"@deepseek-ai/dsh-fs-local",
|
|
55
|
-
"@deepseek-ai/dsh-sandbox",
|
|
56
|
-
"@deepseek-ai/dsh-sandbox-local",
|
|
57
|
-
"@deepseek-ai/dsh-sandbox-policy",
|
|
58
|
-
"@deepseek-ai/dsh-storage-domain"
|
|
59
|
-
];
|
|
60
|
-
/**
|
|
61
|
-
* Packages a full composition provides and a minimal one legitimately omits.
|
|
62
|
-
* Absence is fine; a version that DISAGREES with the required packages is not —
|
|
63
|
-
* that is the mixed-installation failure this contract exists to catch.
|
|
64
|
-
*/
|
|
65
|
-
const OPTIONAL_CORE_PACKAGES = [
|
|
66
|
-
"@deepseek-ai/dsh-tools",
|
|
67
|
-
"@deepseek-ai/dsh-working-directory",
|
|
68
|
-
"@deepseek-ai/dsh-lsp",
|
|
69
|
-
"@deepseek-ai/dsh-lsp-stdio",
|
|
70
|
-
"@deepseek-ai/dsh-api-workspace-files",
|
|
71
|
-
"@deepseek-ai/dsh-typert-protocol",
|
|
72
|
-
"@deepseek-ai/dsh-sandbox-windows-acl",
|
|
73
|
-
"@deepseek-ai/dsh-agent",
|
|
74
|
-
"@deepseek-ai/dsh-agent-instructions",
|
|
75
|
-
"@deepseek-ai/dsh-client-connection",
|
|
76
|
-
"@deepseek-ai/dsh-commands",
|
|
77
|
-
"@deepseek-ai/dsh-llm",
|
|
78
|
-
"@deepseek-ai/dsh-session",
|
|
79
|
-
"@deepseek-ai/dsh-subprocess",
|
|
80
|
-
"@deepseek-ai/dsh-system-prompt"
|
|
81
|
-
];
|
|
82
|
-
/** Every package the contract inspects, required first. */
|
|
83
|
-
const CORE_PACKAGES = [...REQUIRED_CORE_PACKAGES, ...OPTIONAL_CORE_PACKAGES];
|
|
84
|
-
/** Services looked up structurally; older runtimes never install these modules. */
|
|
85
|
-
const HOST_RESOLVED_PACKAGES = ["@deepseek-ai/dsh-working-directory"];
|
|
86
|
-
/** The environment variable that relaxes the gate. */
|
|
87
|
-
const COMPAT_ENFORCEMENT_ENV = "DSH_MULTI_ROOT_COMPAT";
|
|
88
|
-
/**
|
|
89
|
-
* Read one package's declared version through Node resolution.
|
|
90
|
-
*
|
|
91
|
-
* Resolution runs from THIS module, which is what makes the answer meaningful:
|
|
92
|
-
* the upstream packages are peer dependencies, so they resolve to the single
|
|
93
|
-
* copy the host provides — the same copy the providers will subclass at
|
|
94
|
-
* runtime. A package that cannot be resolved is reported absent rather than
|
|
95
|
-
* throwing, because "not installed" is a legitimate answer for every optional
|
|
96
|
-
* package.
|
|
97
|
-
* @param packageName - the package to inspect.
|
|
98
|
-
* @returns the declared version, or `undefined` when the package or its
|
|
99
|
-
* manifest cannot be resolved.
|
|
100
|
-
*/
|
|
101
|
-
function readInstalledVersion(packageName) {
|
|
102
|
-
const require = createRequire(import.meta.url);
|
|
103
|
-
try {
|
|
104
|
-
const manifest = require(`${packageName}/package.json`);
|
|
105
|
-
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
106
|
-
} catch {
|
|
107
|
-
if (!HOST_RESOLVED_PACKAGES.includes(packageName)) return void 0;
|
|
108
|
-
try {
|
|
109
|
-
const manifest = createRequire(require.resolve("@deepseek-ai/dsh/package.json"))(`${packageName}/package.json`);
|
|
110
|
-
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
111
|
-
} catch {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Judge one installation against the contract.
|
|
118
|
-
*
|
|
119
|
-
* The three checks run in this order, and the first failure wins, because each
|
|
120
|
-
* later check would report nonsense about an installation that failed an
|
|
121
|
-
* earlier one: a missing required package has no version to compare, and a
|
|
122
|
-
* mixed installation has no single version to look up in the allowlist.
|
|
123
|
-
* @param readVersion - version reader; defaults to Node resolution. Tests and
|
|
124
|
-
* the static checker pass their own.
|
|
125
|
-
* @returns the report; never throws.
|
|
126
|
-
*/
|
|
127
|
-
function classifyInstallation(readVersion = readInstalledVersion) {
|
|
128
|
-
const packages = CORE_PACKAGES.map((name) => ({
|
|
129
|
-
name,
|
|
130
|
-
version: readVersion(name),
|
|
131
|
-
required: REQUIRED_CORE_PACKAGES.includes(name)
|
|
132
|
-
}));
|
|
133
|
-
const missing = packages.filter((entry) => entry.required && entry.version === void 0);
|
|
134
|
-
if (missing.length > 0) return report("incomplete", void 0, packages, [
|
|
135
|
-
"multi-root workspace: required DSH packages are not installed.",
|
|
136
|
-
"",
|
|
137
|
-
...missing.map((entry) => ` missing: ${entry.name}`)
|
|
138
|
-
]);
|
|
139
|
-
const releases = [...new Set(packages.flatMap((entry) => entry.version === void 0 ? [] : [entry.version]))].sort();
|
|
140
|
-
const [release, ...extra] = releases;
|
|
141
|
-
if (release === void 0) return report("incomplete", void 0, packages, ["multi-root workspace: no DSH package could be inspected."]);
|
|
142
|
-
if (extra.length > 0) return report("mixed", void 0, packages, [
|
|
143
|
-
"multi-root workspace: this installation mixes several DSH releases.",
|
|
144
|
-
"",
|
|
145
|
-
"The filesystem fence and the kernel-sandbox dialects must agree on one upstream",
|
|
146
|
-
"release; a mixed installation means one half of the sandbox was verified against a",
|
|
147
|
-
"shape the other half no longer produces. Align every @deepseek-ai/dsh* package on",
|
|
148
|
-
"one release.",
|
|
149
|
-
"",
|
|
150
|
-
` releases found: ${releases.join(", ")}`
|
|
151
|
-
]);
|
|
152
|
-
if (!SUPPORTED_DSH_RELEASES.includes(release)) return report("unsupported", release, packages, [
|
|
153
|
-
`multi-root workspace: DSH ${release} is not a supported release.`,
|
|
154
|
-
"",
|
|
155
|
-
"This plugin replaces the workspace filesystem fence and the kernel-sandbox provider,",
|
|
156
|
-
"and it recognizes the sandbox profile by the argv shape the upstream provider produces.",
|
|
157
|
-
"Upstream makes no semver promise, so the plugin refuses to grant additional roots on a",
|
|
158
|
-
"release it has never been verified against rather than guess at that shape.",
|
|
159
|
-
"",
|
|
160
|
-
` supported: ${SUPPORTED_DSH_RELEASES.join(", ")}`,
|
|
161
|
-
` installed: ${release}`
|
|
162
|
-
]);
|
|
163
|
-
return report("supported", release, packages, [`multi-root workspace: DSH ${release} is a supported release.`]);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Read the enforcement mode.
|
|
167
|
-
*
|
|
168
|
-
* `warn` exists for exactly one caller: the upgrade smoke, which must run the
|
|
169
|
-
* whole behavior matrix against a release that is deliberately NOT on the
|
|
170
|
-
* allowlist yet — that run is how a release earns its place on the list. It is
|
|
171
|
-
* not a production escape hatch, and the warning says so.
|
|
172
|
-
* @param env - the environment to read; defaults to this process's.
|
|
173
|
-
* @returns `warn` only when explicitly requested, `enforce` otherwise.
|
|
174
|
-
*/
|
|
175
|
-
function compatEnforcement(env = process.env) {
|
|
176
|
-
return env["DSH_MULTI_ROOT_COMPAT"] === "warn" ? "warn" : "enforce";
|
|
177
|
-
}
|
|
178
|
-
/** Compose a report, appending the package inventory and the recovery pointer. */
|
|
179
|
-
function report(verdict, release, packages, lines) {
|
|
180
|
-
return {
|
|
181
|
-
verdict,
|
|
182
|
-
release,
|
|
183
|
-
packages,
|
|
184
|
-
message: (verdict === "supported" ? [...lines] : [
|
|
185
|
-
...lines,
|
|
186
|
-
"",
|
|
187
|
-
"Inspected packages:",
|
|
188
|
-
...packages.map((entry) => ` ${entry.name} ${entry.version ?? "(not installed)"}`),
|
|
189
|
-
"",
|
|
190
|
-
"See docs/troubleshooting/unsupported-dsh-release.md"
|
|
191
|
-
]).join("\n")
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
//#endregion
|
|
195
|
-
//#region src/compat.ts
|
|
196
|
-
/**
|
|
197
|
-
* `multi-root-compat`: the startup gate that turns the DSH compatibility
|
|
198
|
-
* contract from documentation into a precondition.
|
|
199
|
-
*
|
|
200
|
-
* The four security-relevant rows of this bundle — `multi-root-fs`,
|
|
201
|
-
* `multi-root-sandbox`, `multi-root-registry`, `multi-root-instructions` —
|
|
202
|
-
* inject `multiRootCompat`. Cordis will not start a plugin whose injected
|
|
203
|
-
* service is absent, so this row is what decides whether they run at all:
|
|
204
|
-
*
|
|
205
|
-
* ```text
|
|
206
|
-
* compat check passes → ctx.multiRootCompat exists → the providers start
|
|
207
|
-
* compat check fails → the row throws → they never start
|
|
208
|
-
* ```
|
|
209
|
-
*
|
|
210
|
-
* That is why the gate is a plain `apply` and not a `Service` subclass mounted
|
|
211
|
-
* directly: the check has to be able to fail BEFORE the service exists. A
|
|
212
|
-
* `Service` constructor has already run `super(ctx, name)` — and therefore
|
|
213
|
-
* already claimed the service key — by the time it could inspect anything.
|
|
214
|
-
*
|
|
215
|
-
* The verdict itself, and the allowlist it is judged against, live in
|
|
216
|
-
* `./compat/dsh-version.ts`. This module owns only the reaction to it.
|
|
217
|
-
*
|
|
218
|
-
* @module @dsh-electron/dsh-plugin-multi-root-workspace/compat
|
|
219
|
-
*/
|
|
220
|
-
/**
|
|
221
|
-
* Raised when the installed DSH release is not one this plugin is verified
|
|
222
|
-
* against. It is thrown from `apply`, so it surfaces as a plugin load failure
|
|
223
|
-
* with the full diagnosis attached — never as a silently degraded sandbox.
|
|
224
|
-
*/
|
|
225
|
-
var DshCompatUnsupportedError = class extends Error {
|
|
226
|
-
/** The report that produced the refusal. */
|
|
227
|
-
report;
|
|
228
|
-
constructor(report) {
|
|
229
|
-
super(report.message);
|
|
230
|
-
this.name = "DshCompatUnsupportedError";
|
|
231
|
-
this.report = report;
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
/**
|
|
235
|
-
* The `ctx.multiRootCompat` service: the resolved compatibility verdict, held
|
|
236
|
-
* where the gated providers can read it.
|
|
237
|
-
*
|
|
238
|
-
* It intentionally exposes no per-version capability flags. The adapters under
|
|
239
|
-
* `./compat/` detect the shape they need STRUCTURALLY — whether a return value
|
|
240
|
-
* is a thenable, which export name a module carries — because a structural
|
|
241
|
-
* probe also survives upstream reshaping something within one release, while a
|
|
242
|
-
* version comparison does not. The release string here is for the gate and for
|
|
243
|
-
* diagnostics.
|
|
244
|
-
*/
|
|
245
|
-
var MultiRootCompatService = class extends Service {
|
|
246
|
-
/** The verdict this composition started under. */
|
|
247
|
-
report;
|
|
248
|
-
constructor(ctx, report) {
|
|
249
|
-
super(ctx, "multiRootCompat");
|
|
250
|
-
this.report = report;
|
|
251
|
-
}
|
|
252
|
-
/** The single DSH release every inspected core package agreed on. */
|
|
253
|
-
get release() {
|
|
254
|
-
return this.report.release;
|
|
255
|
-
}
|
|
256
|
-
/** Whether the installation is on the allowlist. */
|
|
257
|
-
get supported() {
|
|
258
|
-
return this.report.verdict === "supported";
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
/** This row needs nothing: it is the thing everything else waits for. */
|
|
262
|
-
const inject = [];
|
|
263
|
-
/**
|
|
264
|
-
* Apply the gate policy to one report.
|
|
265
|
-
*
|
|
266
|
-
* Under `DSH_MULTI_ROOT_COMPAT=warn` exactly one verdict is relaxed: an
|
|
267
|
-
* `unsupported` release that every inspected package agrees on. That is the
|
|
268
|
-
* only shape the upgrade smoke probes — a coherent tree on a release the
|
|
269
|
-
* allowlist does not name yet, which is how a release earns its place there.
|
|
270
|
-
* `mixed` and `incomplete` describe an installation the contract cannot judge
|
|
271
|
-
* at all, so they are refused in either mode; production deployments leave the
|
|
272
|
-
* variable unset and get the refusal for everything.
|
|
273
|
-
* @param report - the verdict to act on.
|
|
274
|
-
* @param enforcement - how to react to a non-`supported` verdict.
|
|
275
|
-
* @returns the warning to log, or `undefined` when there is nothing to say.
|
|
276
|
-
* @throws {DshCompatUnsupportedError} when refusing to run.
|
|
277
|
-
*/
|
|
278
|
-
function assertSupportedInstallation(report, enforcement) {
|
|
279
|
-
if (report.verdict === "supported") return void 0;
|
|
280
|
-
if (enforcement === "enforce" || report.verdict !== "unsupported") throw new DshCompatUnsupportedError(report);
|
|
281
|
-
return `${report.message}\n\nProceeding anyway because ${COMPAT_ENFORCEMENT_ENV}=warn. This is an upgrade-smoke mode: additional workspace roots are about to be granted through a sandbox profile shape that has not been verified on this release. Supported releases: ${SUPPORTED_DSH_RELEASES.join(", ")}.`;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Judge the installation, then either refuse to provide the service or provide
|
|
285
|
-
* it.
|
|
286
|
-
* @param ctx - the row's context.
|
|
287
|
-
*/
|
|
288
|
-
function apply(ctx) {
|
|
289
|
-
const report = classifyInstallation();
|
|
290
|
-
const warning = assertSupportedInstallation(report, compatEnforcement());
|
|
291
|
-
if (warning !== void 0) ctx.logger.warn(warning);
|
|
292
|
-
ctx.plugin(MultiRootCompatService, report);
|
|
293
|
-
}
|
|
294
|
-
//#endregion
|
|
295
|
-
export { inject as a, REQUIRED_CORE_PACKAGES as c, compatEnforcement as d, readInstalledVersion as f, assertSupportedInstallation as i, SUPPORTED_DSH_RELEASES as l, MultiRootCompatService as n, CORE_PACKAGES as o, apply as r, OPTIONAL_CORE_PACKAGES as s, DshCompatUnsupportedError as t, classifyInstallation as u };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { canonicalPath } from "@deepseek-ai/dsh-sandbox";
|
|
2
|
-
//#region src/workspace-routing.ts
|
|
3
|
-
/** Resolve relative paths against the primary cwd; never search other roots by basename. */
|
|
4
|
-
async function routeWorkspacePath(ctx, primaryRoot, path, signal, cwd = primaryRoot) {
|
|
5
|
-
signal?.throwIfAborted();
|
|
6
|
-
const primary = canonicalPath(primaryRoot);
|
|
7
|
-
const roots = [primary, ...ctx.multiRootScope.scopeOf(primary)];
|
|
8
|
-
const target = await ctx.fs.resolve(path, {
|
|
9
|
-
cwd,
|
|
10
|
-
...signal === void 0 ? {} : { signal }
|
|
11
|
-
});
|
|
12
|
-
for (const root of roots) {
|
|
13
|
-
const rootTarget = await ctx.fs.resolve(root, signal === void 0 ? {} : { signal });
|
|
14
|
-
if (!ctx.fs.contains(rootTarget, target)) continue;
|
|
15
|
-
if (root !== primary && !ctx.multiRootScope.scopeOf(primary).includes(root)) return void 0;
|
|
16
|
-
signal?.throwIfAborted();
|
|
17
|
-
return {
|
|
18
|
-
primaryRoot: primary,
|
|
19
|
-
workspaceRoot: root,
|
|
20
|
-
target,
|
|
21
|
-
absolutePath: ctx.fs.processPath(target)
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/method-wrapper.ts
|
|
27
|
-
/** Wrap a public method on a Cordis service without capturing a caller-context proxy. */
|
|
28
|
-
function wrapMethod(target, key, wrap) {
|
|
29
|
-
const own = Object.getOwnPropertyDescriptor(target, key);
|
|
30
|
-
let prototype = target;
|
|
31
|
-
let descriptor;
|
|
32
|
-
while (prototype !== null && descriptor === void 0) {
|
|
33
|
-
descriptor = Object.getOwnPropertyDescriptor(prototype, key);
|
|
34
|
-
prototype = Object.getPrototypeOf(prototype);
|
|
35
|
-
}
|
|
36
|
-
if (typeof descriptor?.value !== "function") throw new Error(`multi-root: ${String(key)} is not a public method`);
|
|
37
|
-
const value = wrap(descriptor.value);
|
|
38
|
-
Object.defineProperty(target, key, {
|
|
39
|
-
configurable: true,
|
|
40
|
-
writable: true,
|
|
41
|
-
enumerable: own?.enumerable ?? false,
|
|
42
|
-
value
|
|
43
|
-
});
|
|
44
|
-
return () => {
|
|
45
|
-
if (Object.getOwnPropertyDescriptor(target, key)?.value !== value) return;
|
|
46
|
-
if (own === void 0) Reflect.deleteProperty(target, key);
|
|
47
|
-
else Object.defineProperty(target, key, own);
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { routeWorkspacePath as n, wrapMethod as t };
|
package/lib/sandbox-BRXl_FpF.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { a as splitConfined, i as DialectUnrecognizedError, n as widenWindowsProfile, o as widenProfileArgs } from "./windows-profile-CiFsFYIV.js";
|
|
2
|
-
import { SandboxUnavailableError } from "@deepseek-ai/dsh-sandbox";
|
|
3
|
-
import { LocalSandboxProvider } from "@deepseek-ai/dsh-sandbox-local";
|
|
4
|
-
//#region src/compat/sandbox-confine.ts
|
|
5
|
-
/** Whether a value is a thenable, i.e. whether the installed `confine` is async. */
|
|
6
|
-
function isThenable(value) {
|
|
7
|
-
return typeof value?.then === "function";
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Call the upstream `confine` and widen its result, preserving sync/async shape.
|
|
11
|
-
*
|
|
12
|
-
* @param base - the upstream `confine`, already bound to its provider.
|
|
13
|
-
* @param widen - the pure transformation to apply to the upstream result. It
|
|
14
|
-
* runs exactly once per call, on whichever release; it may throw, and the
|
|
15
|
-
* throw surfaces synchronously or as a rejection to match the base shape.
|
|
16
|
-
* @param argv - the caller's argv, forwarded verbatim.
|
|
17
|
-
* @param policy - the per-call policy, forwarded verbatim.
|
|
18
|
-
* @param signal - forwarded when the installed release accepts it.
|
|
19
|
-
* @returns the widened result, in the shape the installed release uses.
|
|
20
|
-
*/
|
|
21
|
-
function widenConfined(base, widen, argv, policy, signal) {
|
|
22
|
-
const confined = base(argv, policy, signal);
|
|
23
|
-
return isThenable(confined) ? confined.then(widen) : widen(confined);
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/sandbox.ts
|
|
27
|
-
/**
|
|
28
|
-
* `MultiRootSandboxProvider`: the kernel-sandbox dialect provider mounted as
|
|
29
|
-
* `ctx.sandbox`.
|
|
30
|
-
*
|
|
31
|
-
* Every confined execution in this composition funnels through `confine()` —
|
|
32
|
-
* the bash executor wraps `['bash','-c',command]`, and the terminal backend
|
|
33
|
-
* wraps its PTY spawn argv — so widening the grant here is what gives bash, PTY,
|
|
34
|
-
* and the fs fence one and the same root set (requirement §13). The bash
|
|
35
|
-
* executor itself is therefore left upstream: it never computes roots.
|
|
36
|
-
*
|
|
37
|
-
* POSIX widening lives in `./dialects.ts`, Windows capabilities in
|
|
38
|
-
* `./windows-profile.ts` and `./windows-runner.ts`: the upstream profile builders
|
|
39
|
-
* are unreachable in the published package, so the additional roots are grafted
|
|
40
|
-
* onto the profile `super.confine` actually produced (recognize the dialect
|
|
41
|
-
* structurally, clone its grant spelling, fail loudly when the shape is not
|
|
42
|
-
* known). This class owns only the policy that decides WHEN to graft:
|
|
43
|
-
*
|
|
44
|
-
* 1. with no additional roots, or under any mode other than `workspace-write`,
|
|
45
|
-
* the upstream result is returned ELEMENT FOR ELEMENT — same argv, same
|
|
46
|
-
* `enforcement`, same `denialSignatures`, same `runnerFailureRules`;
|
|
47
|
-
* 2. `enforcement`, `denialSignatures`, and `runnerFailureRules` are NEVER
|
|
48
|
-
* recomputed here, even when the argv is widened — the bash executor derives
|
|
49
|
-
* its denial and enforcement reporting from them;
|
|
50
|
-
* 3. only `argv` may differ, and a dialect whose shape cannot be extended fails
|
|
51
|
-
* loudly (`SandboxUnavailableError`) instead of silently confining to the
|
|
52
|
-
* primary root alone.
|
|
53
|
-
*
|
|
54
|
-
* @module @dsh-electron/dsh-plugin-multi-root-workspace/sandbox
|
|
55
|
-
*/
|
|
56
|
-
/**
|
|
57
|
-
* Local process-sandbox provider over the multi-root scope. Registers as
|
|
58
|
-
* `ctx.sandbox`; the runner chain, probing, denial dialects, and Windows ACL
|
|
59
|
-
* grant mechanics stay the upstream implementation's.
|
|
60
|
-
*/
|
|
61
|
-
var MultiRootSandboxProvider = class extends LocalSandboxProvider {
|
|
62
|
-
static inject = [
|
|
63
|
-
"multiRootCompat",
|
|
64
|
-
"sandboxPolicy",
|
|
65
|
-
"multiRootScope"
|
|
66
|
-
];
|
|
67
|
-
/**
|
|
68
|
-
* Wrap `argv` so it executes confined under `policy` on this host, granting
|
|
69
|
-
* the scope's additional roots inside the SAME dialect profile.
|
|
70
|
-
*
|
|
71
|
-
* Under `read-only` nothing is added (the mode denies every write, additional
|
|
72
|
-
* roots included), and `danger-full-access` never reaches here at all: the
|
|
73
|
-
* bash executor and the PTY backend both hand their argv straight to the local
|
|
74
|
-
* runtime in that mode. Widening therefore only ever ADDS the scope's
|
|
75
|
-
* additional roots to an upstream `workspace-write` profile.
|
|
76
|
-
*
|
|
77
|
-
* The return shape is the INSTALLED upstream provider's: synchronous on a
|
|
78
|
-
* release with a synchronous `confine`, a promise on a release with an
|
|
79
|
-
* asynchronous one. `widenConfined` preserves whichever it is — see
|
|
80
|
-
* `./compat/sandbox-confine.ts`.
|
|
81
|
-
* @param argv - the exact argv the caller is about to spawn.
|
|
82
|
-
* @param policy - the file-effect policy this execution runs under.
|
|
83
|
-
* @param signal - cancellation, forwarded to releases that accept it.
|
|
84
|
-
* @returns the argv to spawn instead, plus the selected backend's facts.
|
|
85
|
-
*/
|
|
86
|
-
confine(argv, policy, signal) {
|
|
87
|
-
const base = super.confine;
|
|
88
|
-
return widenConfined(base.bind(this), (confined) => this.widenForScope(confined, argv, policy), argv, policy, signal);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Graft the scope's additional roots onto one upstream `confine` result.
|
|
92
|
-
*
|
|
93
|
-
* Pure with respect to the upstream call: it only ever reads the scope and
|
|
94
|
-
* rewrites `argv`. `enforcement`, `denialSignatures` and `runnerFailureRules`
|
|
95
|
-
* are passed through untouched, because the bash executor derives its denial
|
|
96
|
-
* and enforcement reporting from them.
|
|
97
|
-
* @param confined - the upstream result for this call.
|
|
98
|
-
* @param argv - the caller's argv, needed to re-split the wrapped form.
|
|
99
|
-
* @param policy - the per-call policy.
|
|
100
|
-
* @returns the upstream result element for element, or one with a widened argv.
|
|
101
|
-
*/
|
|
102
|
-
widenForScope(confined, argv, policy) {
|
|
103
|
-
if (policy.mode !== "workspace-write") return confined;
|
|
104
|
-
const scope = this.ctx.multiRootScope.resolve(policy);
|
|
105
|
-
if (scope.additionalRoots.length === 0) return confined;
|
|
106
|
-
try {
|
|
107
|
-
const shape = splitConfined(confined.argv, argv);
|
|
108
|
-
if (shape.dialect === "windows-acl") return {
|
|
109
|
-
...confined,
|
|
110
|
-
argv: [
|
|
111
|
-
...widenWindowsProfile(shape.profileArgs, scope.additionalRoots, scope.primaryRoot),
|
|
112
|
-
"--",
|
|
113
|
-
...argv
|
|
114
|
-
]
|
|
115
|
-
};
|
|
116
|
-
const profileArgs = widenProfileArgs(shape.dialect, shape.profileArgs, policy, scope.additionalRoots);
|
|
117
|
-
return {
|
|
118
|
-
...confined,
|
|
119
|
-
argv: [
|
|
120
|
-
...profileArgs,
|
|
121
|
-
"--",
|
|
122
|
-
...argv
|
|
123
|
-
]
|
|
124
|
-
};
|
|
125
|
-
} catch (error) {
|
|
126
|
-
if (!(error instanceof DialectUnrecognizedError)) throw error;
|
|
127
|
-
throw new SandboxUnavailableError(policy.mode, `multi-root workspace: cannot grant the additional workspace roots [${scope.additionalRoots.join(", ")}] under the primary root ${scope.primaryRoot} — ${error.message}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
//#endregion
|
|
132
|
-
export { widenConfined as n, MultiRootSandboxProvider as t };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/** Lazy additional-root tree and bounded text previews; requests carry a session and exact root. */
|
|
2
|
-
import { type ReactNode } from 'react';
|
|
3
|
-
import type { RootEntryView } from '../contract.ts';
|
|
4
|
-
import type { PanelClient } from './panel-client.ts';
|
|
5
|
-
import type { Translate } from './WorkspaceFoldersAction.tsx';
|
|
6
|
-
export interface RootFileTreeProps {
|
|
7
|
-
panel: PanelClient;
|
|
8
|
-
entry: RootEntryView;
|
|
9
|
-
sessionId: () => string | undefined;
|
|
10
|
-
t: Translate;
|
|
11
|
-
}
|
|
12
|
-
export declare function RootFileTree(props: RootFileTreeProps): ReactNode;
|