@dsh-electron/dsh-plugin-multi-root-workspace 0.1.14 → 0.1.16
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 +32 -1
- package/CHANGELOG.md +32 -1
- package/README.en.md +25 -8
- package/README.md +25 -8
- package/cordis.patch.yml +5 -1
- package/lib/{llm-message-fYORacvh.js → agent-instructions-BXuKhOzr.js} +1 -84
- package/lib/auto-review.js +2 -2
- package/lib/client.js +969 -100
- package/lib/client.js.map +1 -1
- package/lib/{command-Dcz6nULo.js → command-DaVJ-mK3.js} +76 -11
- package/lib/command.js +1 -1
- package/lib/compat-CTJbpCxu.js +267 -0
- package/lib/compat.js +1 -1
- package/lib/{dialects-Dr4rDR-H.js → dialects-CdlG3RF9.js} +1 -1
- package/lib/{compat-veDqCOoa.js → dsh-version-DCwF7REk.js} +2 -264
- package/lib/index.js +10 -8
- package/lib/{instructions-KsUwUFE0.js → instructions-Ca80SkZq.js} +696 -27
- package/lib/instructions.js +1 -1
- package/lib/llm-message-CepyzEBQ.js +84 -0
- package/lib/lsp.js +4 -4
- package/lib/{metadata-DgqSdVX_.js → metadata-99jgViHQ.js} +1 -1
- package/lib/{method-wrapper-CFY3p3j2.js → method-wrapper-D4oUCsEF.js} +22 -2
- package/lib/{native-win32-CRNXr11U.js → native-win32-C5oMtt7f.js} +1 -1
- package/lib/ops-compatibility.js +58 -0
- package/lib/ops-settings-UN2oOKEp.js +40 -0
- package/lib/ops-tools-k4JYaOrM.js +152 -0
- package/lib/process-fence.js +193 -34
- package/lib/{protocol-CnR1KTXy.js → protocol-CwDnFEyK.js} +8 -4
- package/lib/{registry-DR_sMuvS.js → registry-BibiukWk.js} +236 -80
- package/lib/{registry-lease-win32-DDO-c7ig.js → registry-lease-win32-r4puac9m.js} +1 -1
- package/lib/{registry-operation-C2ZV3Jhw.js → registry-operation-CIlmt6_c.js} +5 -1
- package/lib/registry.js +2 -2
- package/lib/{review-context-NDpKeMCc.js → review-context-OxO-fMWR.js} +24 -7
- package/lib/review-context.js +1 -1
- package/lib/{roots-Ca_W1S9n.js → roots-CmaWxRVy.js} +112 -22
- package/lib/{sandbox-C-vCJCp3.js → sandbox-aobdyQGi.js} +7 -4
- package/lib/sandbox.js +1 -1
- package/lib/scope.js +162 -12
- package/lib/skills-utyuvmwr.js +104 -0
- package/lib/skills.js +5 -106
- package/lib/{tool-context-CpgIFcCB.js → tool-context-CCeY3mrK.js} +1 -1
- package/lib/types/authority/protocol.d.ts +5 -1
- package/lib/types/client/files-tree/FilesTree.d.ts +49 -6
- package/lib/types/client/files-tree/adapter.d.ts +69 -16
- package/lib/types/client/files-tree/face.d.ts +31 -2
- package/lib/types/client/files-tree/locate.d.ts +74 -0
- package/lib/types/client/files-tree/navigator.d.ts +98 -0
- package/lib/types/client/index.d.ts +7 -0
- package/lib/types/client/locales.d.ts +30 -0
- package/lib/types/client/ops-settings.d.ts +6 -0
- package/lib/types/client/skills-settings.d.ts +3 -2
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/command.d.ts +3 -3
- package/lib/types/compat/files-tree.d.ts +8 -1
- package/lib/types/compat/forge-entrypoints.d.ts +44 -0
- package/lib/types/compat/instruction-activity.d.ts +32 -1
- package/lib/types/compat/ops-confirmation.d.ts +17 -0
- package/lib/types/compat/ops-settings.d.ts +11 -0
- package/lib/types/compat/ops-tools.d.ts +25 -0
- package/lib/types/compat/session-existence.d.ts +41 -0
- package/lib/types/compat/skills-client.d.ts +1 -0
- package/lib/types/compat/tool-context.d.ts +4 -0
- package/lib/types/compat.d.ts +2 -2
- package/lib/types/instructions.d.ts +6 -1
- package/lib/types/ops-compatibility.d.ts +34 -0
- package/lib/types/registry-operation.d.ts +7 -0
- package/lib/types/registry.d.ts +67 -8
- package/lib/types/review-context.d.ts +2 -0
- package/lib/types/roots.d.ts +116 -20
- package/lib/types/scope.d.ts +95 -3
- package/lib/workspace-files.js +4 -4
- package/lib/{workspace-routing-YPxaQ4V3.js → workspace-routing-D_qwMUh-.js} +4 -4
- package/package.json +5 -1
package/lib/process-fence.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { t as wrapMethod } from "./method-wrapper-
|
|
2
|
-
import {
|
|
3
|
-
import { t as aroundTool } from "./tool-context-
|
|
4
|
-
import {
|
|
1
|
+
import { t as wrapMethod } from "./method-wrapper-D4oUCsEF.js";
|
|
2
|
+
import { c as withRegistryAdmission } from "./registry-operation-CIlmt6_c.js";
|
|
3
|
+
import { t as aroundTool } from "./tool-context-CCeY3mrK.js";
|
|
4
|
+
import { r as opsCompatibilityToken } from "./ops-settings-UN2oOKEp.js";
|
|
5
|
+
import { n as detectDialect, s as confineInstalled } from "./dialects-CdlG3RF9.js";
|
|
6
|
+
import { c as leaveOpsProtection, d as revokeOpsProtection, f as withOpsSpawnPermit, i as classifyOpsTool, n as assertOpsProtectionOwner, o as drainOpsProtection, r as claimOpsProtection, s as enterOpsProtection, t as assertOpsPosixCacheAdmission } from "./ops-tools-k4JYaOrM.js";
|
|
5
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
8
|
//#region src/compat/process-profile.ts
|
|
7
9
|
/** Structural runner recognition shared by the synchronous process seams. */
|
|
@@ -18,11 +20,11 @@ function originalProcessArgv(argv) {
|
|
|
18
20
|
}
|
|
19
21
|
//#endregion
|
|
20
22
|
//#region src/compat/process-result.ts
|
|
21
|
-
const object$
|
|
23
|
+
const object$2 = (value) => typeof value === "object" && value !== null;
|
|
22
24
|
const thenable = (value) => typeof value?.then === "function";
|
|
23
|
-
const textOf = (value) => typeof value === "string" ? value : object$
|
|
24
|
-
const stderrOf = (value) => textOf(value.stderr) + (object$
|
|
25
|
-
const exitCodeOf = (value) => typeof value.exitCode === "number" || value.exitCode === null ? value.exitCode : value.ok === false || object$
|
|
25
|
+
const textOf = (value) => typeof value === "string" ? value : object$2(value) && typeof value.text === "string" ? value.text : "";
|
|
26
|
+
const stderrOf = (value) => textOf(value.stderr) + (object$2(value.error) ? textOf(value.error.message) : "") + (object$2(value.failure) ? textOf(value.failure.message) : "");
|
|
27
|
+
const exitCodeOf = (value) => typeof value.exitCode === "number" || value.exitCode === null ? value.exitCode : value.ok === false || object$2(value.error) || object$2(value.failure) ? 1 : 0;
|
|
26
28
|
/** Denial and runner-failure verdicts for one settled process — the same
|
|
27
29
|
* non-zero-exit + stderr-signature rules the sandbox executors apply: a fatal
|
|
28
30
|
* runner line is an infrastructure failure, never a policy denial. */
|
|
@@ -40,7 +42,7 @@ const classifyOutcome = (exitCode, stderr, facts) => {
|
|
|
40
42
|
const sandboxStamp = (value, facts, policy, stderr) => {
|
|
41
43
|
const { denied, runnerFailed } = classifyOutcome(exitCodeOf(value), stderr ?? stderrOf(value), facts);
|
|
42
44
|
return {
|
|
43
|
-
...object$
|
|
45
|
+
...object$2(value.sandbox) ? value.sandbox : {},
|
|
44
46
|
mode: policy.mode,
|
|
45
47
|
enforcement: facts.enforcement,
|
|
46
48
|
denied,
|
|
@@ -48,7 +50,7 @@ const sandboxStamp = (value, facts, policy, stderr) => {
|
|
|
48
50
|
};
|
|
49
51
|
};
|
|
50
52
|
function stampProcessResult(value, facts, policy) {
|
|
51
|
-
if (!object$
|
|
53
|
+
if (!object$2(value)) return value;
|
|
52
54
|
return {
|
|
53
55
|
...value,
|
|
54
56
|
sandbox: sandboxStamp(value, facts, policy)
|
|
@@ -63,8 +65,8 @@ function stampProcessResult(value, facts, policy) {
|
|
|
63
65
|
*/
|
|
64
66
|
const liveHandle = (value) => thenable(value.done) || typeof value.done === "function" || Object.values(value).some((member) => typeof member === "function") || Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null;
|
|
65
67
|
function decorateProcessOutcome(value, facts, policy, diagnostics) {
|
|
66
|
-
if (object$
|
|
67
|
-
if (object$
|
|
68
|
+
if (object$2(value) && typeof value.then === "function") return value.then((result) => decorateProcessOutcome(result, facts, policy, diagnostics));
|
|
69
|
+
if (object$2(value) && typeof value.result === "function") {
|
|
68
70
|
let cached;
|
|
69
71
|
let settled = false;
|
|
70
72
|
wrapMethod(value, "result", (original) => function(...args) {
|
|
@@ -76,7 +78,7 @@ function decorateProcessOutcome(value, facts, policy, diagnostics) {
|
|
|
76
78
|
});
|
|
77
79
|
return value;
|
|
78
80
|
}
|
|
79
|
-
if (object$
|
|
81
|
+
if (object$2(value) && liveHandle(value)) {
|
|
80
82
|
const settle = () => {
|
|
81
83
|
try {
|
|
82
84
|
value.sandbox = sandboxStamp(value, facts, policy, diagnostics?.stderr?.());
|
|
@@ -140,6 +142,58 @@ function isAsyncProcessEntry(entry) {
|
|
|
140
142
|
return typeof entry === "function" && entry.constructor.name === "AsyncFunction";
|
|
141
143
|
}
|
|
142
144
|
//#endregion
|
|
145
|
+
//#region src/compat/forge-entrypoints.ts
|
|
146
|
+
/**
|
|
147
|
+
* The forge-bundle service entries an admission can wrap, in this order.
|
|
148
|
+
* `worktrees.create`/`restore` take an `Agent` (the session rides on
|
|
149
|
+
* `agent.session`); every listed `forgePanel` entry takes the `Session` as
|
|
150
|
+
* its first argument. Entries not listed — background inspections, the
|
|
151
|
+
* isolated `forge-worktree` instance inside the panel's mount group — stay
|
|
152
|
+
* ledger-covered.
|
|
153
|
+
*/
|
|
154
|
+
const FORGE_PROCESS_SERVICES = [{
|
|
155
|
+
service: "worktrees",
|
|
156
|
+
keys: ["create", "restore"]
|
|
157
|
+
}, {
|
|
158
|
+
service: "forgePanel",
|
|
159
|
+
keys: [
|
|
160
|
+
"branches",
|
|
161
|
+
"track",
|
|
162
|
+
"dismiss",
|
|
163
|
+
"refresh",
|
|
164
|
+
"localDiff",
|
|
165
|
+
"localText",
|
|
166
|
+
"changeRequestChecks",
|
|
167
|
+
"changeRequestDiff",
|
|
168
|
+
"changeRequestText",
|
|
169
|
+
"submitReview",
|
|
170
|
+
"markReady",
|
|
171
|
+
"merge",
|
|
172
|
+
"requestWorktree",
|
|
173
|
+
"cancelWorktree",
|
|
174
|
+
"stopCreation",
|
|
175
|
+
"retryWorktree",
|
|
176
|
+
"restoreWorktree",
|
|
177
|
+
"continueInProject"
|
|
178
|
+
]
|
|
179
|
+
}];
|
|
180
|
+
const object$1 = (value) => typeof value === "object" && value !== null;
|
|
181
|
+
/**
|
|
182
|
+
* Read the session a foreign-service entry resolves its policy from — the
|
|
183
|
+
* first argument alone: a `Session`, or an `Agent`-shaped value carrying one.
|
|
184
|
+
* The probe is deliberately structural and narrow (`id` + `header`): it is a
|
|
185
|
+
* trust boundary over the upstream type, not a full validation — anything
|
|
186
|
+
* else runs unadmitted rather than let `sandboxPolicy.resolve` read fields a
|
|
187
|
+
* foreign argument lacks.
|
|
188
|
+
* @param first - the wrapped call's first argument.
|
|
189
|
+
* @returns the session, or `undefined` for a call that does not carry one.
|
|
190
|
+
*/
|
|
191
|
+
function sessionOf(first) {
|
|
192
|
+
const candidate = object$1(first) && object$1(first.session) ? first.session : first;
|
|
193
|
+
const isSession = (value) => object$1(value) && typeof value.id === "string" && object$1(value.header);
|
|
194
|
+
return isSession(candidate) ? candidate : void 0;
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
143
197
|
//#region src/process-fence.ts
|
|
144
198
|
/**
|
|
145
199
|
* `multi-root-process-fence`: the B9 seam for the one cell `ctx.sandbox.confine`
|
|
@@ -206,9 +260,59 @@ function isThenable(value) {
|
|
|
206
260
|
}
|
|
207
261
|
const object = (value) => typeof value === "object" && value !== null;
|
|
208
262
|
function apply(ctx) {
|
|
263
|
+
const opsScope = ctx.get("multiRootScope");
|
|
264
|
+
const opsSandbox = ctx.sandbox;
|
|
265
|
+
const runOpsDispatch = async (exec, policy, next) => {
|
|
266
|
+
const modeToken = opsCompatibilityToken(ctx);
|
|
267
|
+
const scope = opsScope;
|
|
268
|
+
const opsState = scope.opsProtection;
|
|
269
|
+
const token = enterOpsProtection(opsState);
|
|
270
|
+
try {
|
|
271
|
+
const dispatch = async () => {
|
|
272
|
+
const resolved = scope.resolve(policy);
|
|
273
|
+
if (resolved.authority === "unavailable") throw new Error("multi-root workspace: the registry authority is unavailable; refusing the OPS execution");
|
|
274
|
+
if (resolved.deniedRoots.length > 0) {
|
|
275
|
+
if (policy.mode !== "danger-full-access") throw new Error(`multi-root workspace: the OPS execution is refused in ${policy.mode}: private preparation and worker write boundaries cannot be proven without OPS integration`);
|
|
276
|
+
if (classifyOpsTool(exec.name) === "unknown") throw new Error(`multi-root workspace: the unrecognized OPS capability ${JSON.stringify(exec.name)} is refused while write boundaries apply`);
|
|
277
|
+
if (exec.name === "ops_bash" && typeof exec.arguments === "object" && exec.arguments !== null && exec.arguments.run_in_background === true) throw new Error("multi-root workspace: run_in_background is refused while danger-full-access write boundaries apply");
|
|
278
|
+
}
|
|
279
|
+
let facts;
|
|
280
|
+
if (resolved.deniedRoots.length > 0) {
|
|
281
|
+
if (process.platform === "win32") throw new Error("multi-root workspace: OPS worker preparation is not verified on this platform; refusing the call while write boundaries apply");
|
|
282
|
+
assertOpsPosixCacheAdmission(resolved.deniedRoots);
|
|
283
|
+
facts = await opsSandbox.restrictedExecution(policy, resolved.deniedRoots, exec.signal, resolved.protectedHome);
|
|
284
|
+
if (facts === void 0 || facts.argv.length === 0) throw new Error("multi-root workspace: the restricted runner could not be prepared; refusing the OPS execution");
|
|
285
|
+
}
|
|
286
|
+
assertOpsProtectionOwner(opsState, token);
|
|
287
|
+
if (opsCompatibilityToken(ctx) !== modeToken) throw new Error("multi-root workspace: the OPS compatibility mode changed during dispatch; refusing the execution");
|
|
288
|
+
const store = {
|
|
289
|
+
argvPrefix: facts?.argv ?? [],
|
|
290
|
+
ops: true,
|
|
291
|
+
opsState,
|
|
292
|
+
active: true
|
|
293
|
+
};
|
|
294
|
+
try {
|
|
295
|
+
return await processDenyStore.run(store, () => facts === void 0 ? next() : decorateProcessOutcome(next(), facts, policy, { stderr: () => store.stderr?.() }));
|
|
296
|
+
} finally {
|
|
297
|
+
store.active = false;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
if (ctx.get("multiRootRegistry")?.shared) return await withRegistryAdmission(ctx, policy, "process", dispatch);
|
|
301
|
+
return await dispatch();
|
|
302
|
+
} finally {
|
|
303
|
+
leaveOpsProtection(opsState);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
209
306
|
aroundTool(ctx, async (exec, next) => {
|
|
210
|
-
|
|
211
|
-
|
|
307
|
+
const kind = classifyOpsTool(exec.name);
|
|
308
|
+
if (kind === "other" || kind === "publish" || opsCompatibilityToken(ctx) === void 0) {
|
|
309
|
+
if (!ctx.get("multiRootRegistry")?.shared || exec.agent === void 0) return next();
|
|
310
|
+
const policy = ctx.sandboxPolicy.resolve({ session: exec.agent.session });
|
|
311
|
+
return opsScope.withToolCap(exec.name, () => withRegistryAdmission(ctx, policy, "process", next));
|
|
312
|
+
}
|
|
313
|
+
if (exec.agent === void 0) throw new Error(`multi-root workspace: the OPS call ${JSON.stringify(exec.name)} cannot be confirmed against a trusted session`);
|
|
314
|
+
const policy = ctx.sandboxPolicy.resolve({ session: exec.agent.session });
|
|
315
|
+
return opsScope.withToolCap(exec.name, () => runOpsDispatch(exec, policy, next));
|
|
212
316
|
});
|
|
213
317
|
const policyOf = (spec) => spec?.sandboxPolicy ?? ctx.sandboxPolicy.resolve();
|
|
214
318
|
/**
|
|
@@ -240,27 +344,46 @@ function apply(ctx) {
|
|
|
240
344
|
return isThenable(prepared) ? prepared.then(run) : run(prepared);
|
|
241
345
|
};
|
|
242
346
|
ctx.inject(["subprocess"], (scope) => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
argv
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
347
|
+
const opsState = opsScope.opsProtection;
|
|
348
|
+
scope.effect(() => {
|
|
349
|
+
const restore = wrapMethod(scope.get("subprocess"), "spawn", (original) => function(spec) {
|
|
350
|
+
const store = processDenyStore.getStore();
|
|
351
|
+
if (store?.ops === true && (store.active === false || store.opsState !== opsState)) throw new Error("multi-root workspace: the OPS execution domain has expired");
|
|
352
|
+
const admissionScope = store?.ops === true ? opsScope : scope.multiRootScope;
|
|
353
|
+
if (admissionScope.admissionRequired && admissionScope.hasAdmission() && !admissionScope.admissionPathsValid()) throw new Error("multi-root workspace: an admitted root was redirected before process launch");
|
|
354
|
+
let argv = spec.argv;
|
|
355
|
+
if (store?.ops === true) {
|
|
356
|
+
const prefix = store.argvPrefix;
|
|
357
|
+
if (hasConfinedProfile(spec.argv)) {
|
|
358
|
+
if (!(spec.argv.length > prefix.length && prefix.every((segment, index) => spec.argv[index] === segment))) throw new Error("multi-root workspace: a confined spawn inside an OPS execution domain must carry this domain's own profile");
|
|
359
|
+
} else argv = [...prefix, ...spec.argv];
|
|
360
|
+
if (opsScope.admissionRequired && (hasConfinedProfile(spec.argv) || prefix.length > 0) && !opsScope.permitsOperationProfile(argv)) throw new Error("multi-root workspace: a confined spawn requires a profile from this live admission");
|
|
361
|
+
} else {
|
|
362
|
+
argv = store === void 0 ? spec.argv : [...store.argvPrefix, ...spec.argv];
|
|
363
|
+
if (scope.multiRootScope.admissionRequired && (store !== void 0 || hasConfinedProfile(argv)) && !scope.multiRootScope.permitsProfile(argv)) throw new Error("multi-root workspace: a confined spawn requires a profile from this live admission");
|
|
259
364
|
}
|
|
365
|
+
const launch = () => original.call(this, argv === spec.argv ? spec : {
|
|
366
|
+
...spec,
|
|
367
|
+
argv
|
|
368
|
+
});
|
|
369
|
+
const handle = store !== void 0 || admissionScope.admissionRequired && admissionScope.permitsOperationProfile(argv) ? withOpsSpawnPermit(opsState, launch) : launch();
|
|
370
|
+
if (store === void 0) return handle;
|
|
371
|
+
const stderr = object(handle) && object(handle.collected) && object(handle.collected.stderr) && typeof handle.collected.stderr.readFrom === "function" ? handle.collected.stderr : void 0;
|
|
372
|
+
if (stderr !== void 0) store.stderr = () => {
|
|
373
|
+
try {
|
|
374
|
+
return stderr.readFrom(0).text;
|
|
375
|
+
} catch {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
return handle;
|
|
380
|
+
});
|
|
381
|
+
return async () => {
|
|
382
|
+
await drainOpsProtection(opsState);
|
|
383
|
+
restore();
|
|
260
384
|
};
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
scope.effect(() => wrapMethod(scope.subprocess, "spawnTerminal", (original) => async function(spec) {
|
|
385
|
+
});
|
|
386
|
+
scope.effect(() => wrapMethod(scope.get("subprocess"), "spawnTerminal", (original) => async function(spec) {
|
|
264
387
|
const ptySessionId = spec.env?.DSH_PTY_SESSION_ID;
|
|
265
388
|
if (ptySessionId === void 0 || ptySessionId === "") return await original.call(this, spec);
|
|
266
389
|
const sessionId = spec.env?.DSH_SESSION_ID;
|
|
@@ -293,6 +416,11 @@ function apply(ctx) {
|
|
|
293
416
|
});
|
|
294
417
|
});
|
|
295
418
|
}));
|
|
419
|
+
const token = claimOpsProtection(opsState);
|
|
420
|
+
scope.effect(() => async () => {
|
|
421
|
+
revokeOpsProtection(opsState, token);
|
|
422
|
+
await drainOpsProtection(opsState);
|
|
423
|
+
});
|
|
296
424
|
});
|
|
297
425
|
/**
|
|
298
426
|
* The wrapper every execute-style consumer entry shares: resolve the policy
|
|
@@ -325,6 +453,37 @@ function apply(ctx) {
|
|
|
325
453
|
if (runtime === void 0) return;
|
|
326
454
|
for (const key of ptcEntrypoints(runtime)) deniedEntry(scope, runtime, key);
|
|
327
455
|
});
|
|
456
|
+
const admitCalls = (service, keys) => {
|
|
457
|
+
ctx.inject([service], (scope) => {
|
|
458
|
+
const target = scope.get(service);
|
|
459
|
+
if (target === void 0) return;
|
|
460
|
+
for (const key of keys) try {
|
|
461
|
+
if (!isAsyncProcessEntry(target[key])) {
|
|
462
|
+
if (key in target) ctx.logger.warn(`multi-root workspace: foreign process entry ${service}.${key} exists but is not wrappable and stays outside the admission; any confined spawn it performs relies on the ledger`);
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
scope.effect(() => wrapMethod(target, key, (original) => async function(first, ...rest) {
|
|
466
|
+
const session = sessionOf(first);
|
|
467
|
+
if (session === void 0) return original.call(this, first, ...rest);
|
|
468
|
+
const policy = ctx.sandboxPolicy.resolve({ session });
|
|
469
|
+
let ran = false;
|
|
470
|
+
try {
|
|
471
|
+
return await withRegistryAdmission(ctx, policy, "process", () => {
|
|
472
|
+
ran = true;
|
|
473
|
+
return original.call(this, first, ...rest);
|
|
474
|
+
});
|
|
475
|
+
} catch (error) {
|
|
476
|
+
if (ran) throw error;
|
|
477
|
+
ctx.logger.warn(`multi-root workspace: admission for ${service}.${key} is unavailable; running unadmitted: ${error instanceof Error ? error.message : String(error)}`);
|
|
478
|
+
return original.call(this, first, ...rest);
|
|
479
|
+
}
|
|
480
|
+
}));
|
|
481
|
+
} catch (error) {
|
|
482
|
+
ctx.logger.warn(`multi-root workspace: foreign process entry ${service}.${key} is not wrappable: ${error instanceof Error ? error.message : String(error)}`);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
};
|
|
486
|
+
for (const { service, keys } of FORGE_PROCESS_SERVICES) admitCalls(service, keys);
|
|
328
487
|
}
|
|
329
488
|
//#endregion
|
|
330
489
|
export { apply, inject };
|
|
@@ -212,7 +212,7 @@ function posix$1() {
|
|
|
212
212
|
return posixPromise ??= loadPosix();
|
|
213
213
|
}
|
|
214
214
|
async function connectNative(endpoint) {
|
|
215
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
215
|
+
if (process.platform === "win32") return (await import("./native-win32-C5oMtt7f.js")).connectWindows(endpoint);
|
|
216
216
|
const api = await posix$1(), address = api.address(endpoint), fd = api.open();
|
|
217
217
|
if (api.connect(fd, address, address.length) !== 0) {
|
|
218
218
|
closeSync(fd);
|
|
@@ -222,7 +222,7 @@ async function connectNative(endpoint) {
|
|
|
222
222
|
}
|
|
223
223
|
/** Called only by the kernel lease holder. Never removes another epoch's socket. */
|
|
224
224
|
async function listenNative(endpoint, accepted) {
|
|
225
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
225
|
+
if (process.platform === "win32") return (await import("./native-win32-C5oMtt7f.js")).listenWindows(endpoint, accepted);
|
|
226
226
|
const api = await posix$1(), address = api.address(endpoint), fd = api.open();
|
|
227
227
|
try {
|
|
228
228
|
unlinkSync(endpoint);
|
|
@@ -264,7 +264,7 @@ async function listenNative(endpoint, accepted) {
|
|
|
264
264
|
}
|
|
265
265
|
/** Capability probe for native tests and diagnostics; not an authorization bypass. */
|
|
266
266
|
async function nativeHostAvailability() {
|
|
267
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
267
|
+
if (process.platform === "win32") return (await import("./native-win32-C5oMtt7f.js")).windowsHostAvailability();
|
|
268
268
|
if (process.platform === "linux") {
|
|
269
269
|
if (!/^NoNewPrivs:\s+0$/m.test(readFileSync("/proc/self/status", "utf8"))) return {
|
|
270
270
|
available: false,
|
|
@@ -345,7 +345,11 @@ const rootSchema = z.object({
|
|
|
345
345
|
"invalid"
|
|
346
346
|
]),
|
|
347
347
|
detail: z.string().optional(),
|
|
348
|
-
invalidReason: z.
|
|
348
|
+
invalidReason: z.enum([
|
|
349
|
+
"membership-conflict",
|
|
350
|
+
"protected-path",
|
|
351
|
+
"primary-overlap"
|
|
352
|
+
]).optional()
|
|
349
353
|
}).strict();
|
|
350
354
|
const snapshotSchema = z.object({
|
|
351
355
|
protocol: z.literal(1),
|