@dsh-electron/dsh-plugin-multi-root-workspace 0.1.14 → 0.1.15
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 +20 -1
- package/CHANGELOG.md +20 -1
- package/README.en.md +24 -7
- package/README.md +24 -7
- 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 +208 -26
- package/lib/client.js.map +1 -1
- package/lib/{command-Dcz6nULo.js → command-y5tfcAeC.js} +21 -10
- 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-Ck9wp4J4.js} +695 -26
- package/lib/instructions.js +1 -1
- package/lib/llm-message-CepyzEBQ.js +84 -0
- package/lib/lsp.js +3 -3
- 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 +100 -24
- package/lib/{protocol-CnR1KTXy.js → protocol-CwDnFEyK.js} +8 -4
- package/lib/{registry-DR_sMuvS.js → registry-DyDNDSJZ.js} +235 -79
- package/lib/{registry-lease-win32-DDO-c7ig.js → registry-lease-win32-r4puac9m.js} +1 -1
- package/lib/registry.js +2 -2
- package/lib/{review-context-NDpKeMCc.js → review-context-B-oHkU6a.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-CZElTNPz.js} +1 -1
- package/lib/sandbox.js +1 -1
- package/lib/scope.js +72 -9
- package/lib/skills-utyuvmwr.js +104 -0
- package/lib/skills.js +4 -105
- 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/locales.d.ts +28 -0
- package/lib/types/client/ops-settings.d.ts +6 -0
- package/lib/types/client/skills-settings.d.ts +3 -2
- package/lib/types/command.d.ts +3 -3
- 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/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.d.ts +67 -8
- package/lib/types/review-context.d.ts +2 -0
- package/lib/types/roots.d.ts +114 -20
- package/lib/types/scope.d.ts +28 -2
- package/lib/workspace-files.js +3 -3
- package/lib/{workspace-routing-YPxaQ4V3.js → workspace-routing-D_qwMUh-.js} +4 -4
- package/package.json +5 -1
package/lib/skills.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { t as wrapMethod } from "./method-wrapper-
|
|
1
|
+
import { t as wrapMethod } from "./method-wrapper-D4oUCsEF.js";
|
|
2
2
|
import { c as withRegistryRead } from "./registry-operation-C2ZV3Jhw.js";
|
|
3
|
-
import {
|
|
4
|
-
import { n as skillsMetadataValid } from "./metadata-
|
|
3
|
+
import { t as createInstructionMessage } from "./llm-message-CepyzEBQ.js";
|
|
4
|
+
import { n as skillsMetadataValid } from "./metadata-99jgViHQ.js";
|
|
5
|
+
import { a as skillOrigin, i as skillAgent, n as filesystemSkillsApi, o as volatileField, r as observedSkillOrigin, t as configValue } from "./skills-utyuvmwr.js";
|
|
5
6
|
import { constants, statSync } from "node:fs";
|
|
6
7
|
import { createHash } from "node:crypto";
|
|
7
8
|
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
@@ -10,108 +11,6 @@ import { canonicalPath } from "@deepseek-ai/dsh-sandbox";
|
|
|
10
11
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
12
|
import { lstat, open, readdir, stat } from "node:fs/promises";
|
|
12
13
|
import z from "@deepseek-ai/schemastery";
|
|
13
|
-
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/usingCtx.js
|
|
14
|
-
function _usingCtx() {
|
|
15
|
-
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
16
|
-
var n = Error();
|
|
17
|
-
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
18
|
-
}, e = {}, n = [];
|
|
19
|
-
function using(r, e) {
|
|
20
|
-
if (null != e) {
|
|
21
|
-
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
22
|
-
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
23
|
-
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
24
|
-
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
25
|
-
t && (o = function o() {
|
|
26
|
-
try {
|
|
27
|
-
t.call(e);
|
|
28
|
-
} catch (r) {
|
|
29
|
-
return Promise.reject(r);
|
|
30
|
-
}
|
|
31
|
-
}), n.push({
|
|
32
|
-
v: e,
|
|
33
|
-
d: o,
|
|
34
|
-
a: r
|
|
35
|
-
});
|
|
36
|
-
} else r && n.push({
|
|
37
|
-
d: e,
|
|
38
|
-
a: r
|
|
39
|
-
});
|
|
40
|
-
return e;
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
e,
|
|
44
|
-
u: using.bind(null, !1),
|
|
45
|
-
a: using.bind(null, !0),
|
|
46
|
-
d: function d() {
|
|
47
|
-
var o, t = this.e, s = 0;
|
|
48
|
-
function next() {
|
|
49
|
-
for (; o = n.pop();) try {
|
|
50
|
-
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
51
|
-
if (o.d) {
|
|
52
|
-
var r = o.d.call(o.v);
|
|
53
|
-
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
54
|
-
} else s |= 1;
|
|
55
|
-
} catch (r) {
|
|
56
|
-
return err(r);
|
|
57
|
-
}
|
|
58
|
-
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
59
|
-
if (t !== e) throw t;
|
|
60
|
-
}
|
|
61
|
-
function err(n) {
|
|
62
|
-
return t = t !== e ? new r(n, t) : n, next();
|
|
63
|
-
}
|
|
64
|
-
return next();
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
//#endregion
|
|
69
|
-
//#region src/compat/skills.ts
|
|
70
|
-
/** Never infer authority from cwd, a preset key, or a lookalike Agent. */
|
|
71
|
-
function skillAgent(ctx, options) {
|
|
72
|
-
const scope = options.scope;
|
|
73
|
-
if (typeof scope !== "object" || scope === null || !("id" in scope) || typeof scope.id !== "string") return void 0;
|
|
74
|
-
const agent = ctx.get("agents")?.get(scope.id);
|
|
75
|
-
return agent === scope ? agent : void 0;
|
|
76
|
-
}
|
|
77
|
-
function skillOrigin(ctx, options) {
|
|
78
|
-
const cwd = skillAgent(ctx, options)?.session.header.cwd;
|
|
79
|
-
return typeof cwd === "string" && cwd !== "" ? canonicalPath(cwd) : void 0;
|
|
80
|
-
}
|
|
81
|
-
/** Absence is optional; a present but broken module must fail visibly. */
|
|
82
|
-
async function filesystemSkillsApi() {
|
|
83
|
-
if (!isPackageInstalled("@deepseek-ai/dsh-skill-filesystem")) return void 0;
|
|
84
|
-
const api = await import("@deepseek-ai/dsh-skill-filesystem");
|
|
85
|
-
if (typeof api.FileSystemSkillProvider !== "function") throw new Error("multi-root skills: FileSystemSkillProvider is unavailable");
|
|
86
|
-
return api;
|
|
87
|
-
}
|
|
88
|
-
function volatileField(schema) {
|
|
89
|
-
const method = schema.volatile;
|
|
90
|
-
return typeof method === "function" ? method.call(schema) : schema;
|
|
91
|
-
}
|
|
92
|
-
function configValue(value) {
|
|
93
|
-
if (typeof value === "object" && value !== null && Symbol.for("cosmokit.volatile.write") in value) {
|
|
94
|
-
const get = value.get;
|
|
95
|
-
if (typeof get === "function") return get.call(value);
|
|
96
|
-
}
|
|
97
|
-
return value;
|
|
98
|
-
}
|
|
99
|
-
/** Cold Browser Catalog supplies a Session header, never a fabricated Agent. */
|
|
100
|
-
async function observedSkillOrigin(ctx, sessionId) {
|
|
101
|
-
try {
|
|
102
|
-
var _usingCtx$1 = _usingCtx();
|
|
103
|
-
const query = ctx.get("sessionQuery");
|
|
104
|
-
if (query === void 0) throw new Error("multi-root skills: SessionQuery is unavailable");
|
|
105
|
-
const cwd = _usingCtx$1.u(await query.observeSession(sessionId)).header.cwd;
|
|
106
|
-
if (typeof cwd !== "string" || cwd === "") throw new Error("multi-root skills: Session has no origin");
|
|
107
|
-
return canonicalPath(cwd);
|
|
108
|
-
} catch (_) {
|
|
109
|
-
_usingCtx$1.e = _;
|
|
110
|
-
} finally {
|
|
111
|
-
_usingCtx$1.d();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
//#endregion
|
|
115
14
|
//#region src/skills/reader.ts
|
|
116
15
|
/** Constrain the native parser before discovery can read a candidate's body. */
|
|
117
16
|
function containsPath(root, target) {
|
|
@@ -29,7 +29,11 @@ export declare const snapshotSchema: z.ZodObject<{
|
|
|
29
29
|
invalid: "invalid";
|
|
30
30
|
}>;
|
|
31
31
|
detail: z.ZodOptional<z.ZodString>;
|
|
32
|
-
invalidReason: z.ZodOptional<z.
|
|
32
|
+
invalidReason: z.ZodOptional<z.ZodEnum<{
|
|
33
|
+
"membership-conflict": "membership-conflict";
|
|
34
|
+
"protected-path": "protected-path";
|
|
35
|
+
"primary-overlap": "primary-overlap";
|
|
36
|
+
}>>;
|
|
33
37
|
}, z.core.$strict>>;
|
|
34
38
|
available: z.ZodBoolean;
|
|
35
39
|
}, z.core.$strict>;
|
|
@@ -21,6 +21,16 @@ export declare const zh: {
|
|
|
21
21
|
'autoReview.loadFailed': string;
|
|
22
22
|
'autoReview.restartRequired': string;
|
|
23
23
|
'autoReview.settingsFailed': string;
|
|
24
|
+
'ops.compatibilityEnable': string;
|
|
25
|
+
'ops.experimental': string;
|
|
26
|
+
'ops.compatibilityHint': string;
|
|
27
|
+
'ops.settingsFailed': string;
|
|
28
|
+
'ops.confirmTitle': string;
|
|
29
|
+
'ops.confirmDescription': string;
|
|
30
|
+
'ops.confirmAcknowledge': string;
|
|
31
|
+
'ops.confirmCancel': string;
|
|
32
|
+
'ops.confirmClose': string;
|
|
33
|
+
'ops.confirmEnable': string;
|
|
24
34
|
'skills.userOnly': string;
|
|
25
35
|
'panel.skills': string;
|
|
26
36
|
'panel.skillsEnabled': string;
|
|
@@ -65,6 +75,7 @@ export declare const zh: {
|
|
|
65
75
|
'panel.copied': string;
|
|
66
76
|
'panel.reveal': string;
|
|
67
77
|
'panel.reRegister': string;
|
|
78
|
+
'panel.redirectedHint': string;
|
|
68
79
|
'panel.moveUp': string;
|
|
69
80
|
'panel.moveDown': string;
|
|
70
81
|
'access.inherit': string;
|
|
@@ -101,6 +112,9 @@ export declare const zh: {
|
|
|
101
112
|
'error.copy-failed': string;
|
|
102
113
|
'error.session-not-found': string;
|
|
103
114
|
'error.unsupported-path': string;
|
|
115
|
+
'error.protected-path': string;
|
|
116
|
+
'error.protected-boundary-unknown': string;
|
|
117
|
+
'error.revive-target-changed': string;
|
|
104
118
|
'error.fallback': string;
|
|
105
119
|
};
|
|
106
120
|
/** The canonical key set. */
|
|
@@ -116,6 +130,16 @@ export declare const en: {
|
|
|
116
130
|
'autoReview.loadFailed': string;
|
|
117
131
|
'autoReview.restartRequired': string;
|
|
118
132
|
'autoReview.settingsFailed': string;
|
|
133
|
+
'ops.compatibilityEnable': string;
|
|
134
|
+
'ops.experimental': string;
|
|
135
|
+
'ops.compatibilityHint': string;
|
|
136
|
+
'ops.settingsFailed': string;
|
|
137
|
+
'ops.confirmTitle': string;
|
|
138
|
+
'ops.confirmDescription': string;
|
|
139
|
+
'ops.confirmAcknowledge': string;
|
|
140
|
+
'ops.confirmCancel': string;
|
|
141
|
+
'ops.confirmClose': string;
|
|
142
|
+
'ops.confirmEnable': string;
|
|
119
143
|
'skills.userOnly': string;
|
|
120
144
|
'panel.skills': string;
|
|
121
145
|
'panel.skillsEnabled': string;
|
|
@@ -160,6 +184,7 @@ export declare const en: {
|
|
|
160
184
|
'panel.copied': string;
|
|
161
185
|
'panel.reveal': string;
|
|
162
186
|
'panel.reRegister': string;
|
|
187
|
+
'panel.redirectedHint': string;
|
|
163
188
|
'panel.moveUp': string;
|
|
164
189
|
'panel.moveDown': string;
|
|
165
190
|
'access.inherit': string;
|
|
@@ -196,6 +221,9 @@ export declare const en: {
|
|
|
196
221
|
'error.copy-failed': string;
|
|
197
222
|
'error.session-not-found': string;
|
|
198
223
|
'error.unsupported-path': string;
|
|
224
|
+
'error.protected-path': string;
|
|
225
|
+
'error.protected-boundary-unknown': string;
|
|
226
|
+
'error.revive-target-changed': string;
|
|
199
227
|
'error.fallback': string;
|
|
200
228
|
};
|
|
201
229
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SkillsForm } from '../compat/skills-client.ts';
|
|
2
|
+
import type { Translate } from './WorkspaceFoldersAction.tsx';
|
|
3
|
+
export declare function OpsCompatibilitySettingsCard({ form, t }: {
|
|
4
|
+
form: SkillsForm;
|
|
5
|
+
t: Translate;
|
|
6
|
+
}): import("react").JSX.Element | null;
|
|
@@ -10,12 +10,13 @@ export declare function SkillsSettingsCard({ form, t }: CardProps): import("reac
|
|
|
10
10
|
/**
|
|
11
11
|
* The bundle's one `plugins.bundle.config` cell: every plugin-level switch the
|
|
12
12
|
* package offers, in display order. Each row owns its own form and write path —
|
|
13
|
-
* Skills through
|
|
13
|
+
* Skills and OPS through their settings namespaces, Auto Review through the Plugin
|
|
14
14
|
* Manager's Loader-row enablement — so one cell never serializes their state.
|
|
15
15
|
*/
|
|
16
|
-
export declare function BundleSettingsCard({ form, autoReviewForm, t }: {
|
|
16
|
+
export declare function BundleSettingsCard({ form, autoReviewForm, opsForm, t }: {
|
|
17
17
|
form?: SkillsForm | undefined;
|
|
18
18
|
autoReviewForm?: AutoReviewForm | undefined;
|
|
19
|
+
opsForm?: SkillsForm | undefined;
|
|
19
20
|
t: Translate;
|
|
20
21
|
}): import("react").JSX.Element;
|
|
21
22
|
export declare function installSkillsSettingsCard(ctx: Context, t: Translate): void;
|
package/lib/types/command.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The user-facing surface: the `/workspace-folders` command
|
|
3
|
-
* RPC channel.
|
|
2
|
+
* The user-facing surface: the `/workspace-folders` command, its `/add-dirs`
|
|
3
|
+
* alias for adding a root, and the panel's RPC channel.
|
|
4
4
|
*
|
|
5
5
|
* They share one module because they are one thing — the operator-facing edge
|
|
6
6
|
* over `ctx.multiRootRegistry`. The command serves the text surfaces (the
|
|
@@ -81,7 +81,7 @@ export declare function apply(ctx: Context, config?: CommandConfig): void;
|
|
|
81
81
|
*
|
|
82
82
|
* @param ctx - the host context that may carry `sessions`.
|
|
83
83
|
* @param sessionId - the id the panel sent; already required by the wire schema.
|
|
84
|
-
* @returns the
|
|
84
|
+
* @returns the session's cwd spelling, verbatim — the Registry key.
|
|
85
85
|
* @throws {RootValidationError} `session-not-found` when the service is absent,
|
|
86
86
|
* the id does not name a live session, or that session has no cwd.
|
|
87
87
|
*/
|
|
@@ -9,9 +9,40 @@ export type FileActivity = {
|
|
|
9
9
|
failed: boolean;
|
|
10
10
|
};
|
|
11
11
|
export declare function ptcFileActivity(event: unknown): FileActivity | undefined;
|
|
12
|
+
export declare function stableOpsJson(value: unknown): string;
|
|
13
|
+
export declare const opsActivityEvidenceKey: (kind: "native" | "ptc", id: string, name: string, args: unknown) => string;
|
|
14
|
+
export interface OpsActivityEvidence {
|
|
15
|
+
readonly targets: readonly OpsFileTarget[];
|
|
16
|
+
readonly complete: boolean;
|
|
17
|
+
}
|
|
12
18
|
/** Rebuild read-only discovery candidates from successful durable activity after resume. */
|
|
13
|
-
export declare function replayedInstructionTargets(events: readonly unknown[], origin: string | undefined
|
|
19
|
+
export declare function replayedInstructionTargets(events: readonly unknown[], origin: string | undefined, liveOpsEvidence?: ReadonlyMap<string, OpsActivityEvidence>, pendingExec?: {
|
|
20
|
+
readonly callId: string;
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly arguments: unknown;
|
|
23
|
+
readonly parent?: unknown;
|
|
24
|
+
}, options?: {
|
|
25
|
+
readonly opsCompatibility?: boolean;
|
|
26
|
+
}): readonly string[];
|
|
14
27
|
/** fs tools whose success touches the file at their `file_path` argument. */
|
|
15
28
|
export declare const FILE_TOUCH_TOOL_NAMES: Record<string, true>;
|
|
16
29
|
/** One explicit fs-tool target, shared with live touch capture. */
|
|
17
30
|
export declare function touchedPathOfToolCall(name: string, argumentsJson: string): string | undefined;
|
|
31
|
+
export interface OpsFileActivityInput {
|
|
32
|
+
name: string;
|
|
33
|
+
args: unknown;
|
|
34
|
+
cwd: string | undefined;
|
|
35
|
+
finalValue: unknown;
|
|
36
|
+
observedPaths: readonly string[];
|
|
37
|
+
isError?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface OpsFileTarget {
|
|
40
|
+
path: string;
|
|
41
|
+
kind: 'read' | 'write' | 'remove';
|
|
42
|
+
}
|
|
43
|
+
export interface OpsFileActivity {
|
|
44
|
+
targets: readonly OpsFileTarget[];
|
|
45
|
+
complete: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function normalizeOpsFileActivity(input: OpsFileActivityInput): OpsFileActivity;
|
|
48
|
+
export declare function pendingInstructionTargets(name: string, args: unknown): readonly string[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Keep the optional host confirmation component behind a structural probe. */
|
|
2
|
+
import type { ComponentType } from 'react';
|
|
3
|
+
export interface OpsConfirmationProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
acknowledgeLabel: string;
|
|
8
|
+
cancelLabel: string;
|
|
9
|
+
closeLabel: string;
|
|
10
|
+
confirmLabel: string;
|
|
11
|
+
acknowledged: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onAcknowledgedChange(value: boolean): void;
|
|
14
|
+
onCancel(): void;
|
|
15
|
+
onConfirm(): void;
|
|
16
|
+
}
|
|
17
|
+
export declare function opsRiskConfirmation(): ComponentType<OpsConfirmationProps> | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Context, Fiber } from '@deepseek-ai/cordis';
|
|
2
|
+
export declare const OPS_SETTINGS_ID = "multi-root-ops-compatibility";
|
|
3
|
+
/** Product availability policy, independent of structural Settings adaptation. */
|
|
4
|
+
export declare function opsCompatibilityRelease(release: string | undefined): boolean;
|
|
5
|
+
/** Unsupported hosts retain the config input but expose no editable live field. */
|
|
6
|
+
export declare function opsCompatibilityField<S>(schema: S): S;
|
|
7
|
+
export declare function installOpsCompatibilitySettings(ctx: Context, initial: () => unknown, changed: () => void): {
|
|
8
|
+
read(): unknown;
|
|
9
|
+
fiber: Fiber;
|
|
10
|
+
};
|
|
11
|
+
export declare function opsCompatibilityToken(ctx: Context): object | undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { MultiRootScopeService } from '../scope.ts';
|
|
3
|
+
import type { ToolCaller } from './tool-context.ts';
|
|
4
|
+
export declare const OPS_TOOL_PREFIX = "ops_";
|
|
5
|
+
export declare const OPS_EXEC_NAMES: readonly string[];
|
|
6
|
+
export type OpsToolKind = 'exec' | 'publish' | 'unknown' | 'other';
|
|
7
|
+
export declare function classifyOpsTool(name: string): OpsToolKind;
|
|
8
|
+
export interface OpsProtectionState {
|
|
9
|
+
owner: object | undefined;
|
|
10
|
+
entered: number;
|
|
11
|
+
readonly drainWaiters: Set<() => void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function withOpsSpawnPermit<T>(state: OpsProtectionState, body: () => T): T;
|
|
14
|
+
export declare function opsSpawnPermitted(state: OpsProtectionState): boolean;
|
|
15
|
+
export declare function createOpsProtectionState(): OpsProtectionState;
|
|
16
|
+
export declare function claimOpsProtection(state: OpsProtectionState): object;
|
|
17
|
+
export declare function revokeOpsProtection(state: OpsProtectionState, token: object): void;
|
|
18
|
+
export declare function opsProtectionReady(state: OpsProtectionState): boolean;
|
|
19
|
+
export declare function assertOpsProtectionReady(state: OpsProtectionState): void;
|
|
20
|
+
export declare function assertOpsProtectionOwner(state: OpsProtectionState, token: object): void;
|
|
21
|
+
export declare function enterOpsProtection(state: OpsProtectionState): object;
|
|
22
|
+
export declare function leaveOpsProtection(state: OpsProtectionState): void;
|
|
23
|
+
export declare function drainOpsProtection(state: OpsProtectionState): Promise<void>;
|
|
24
|
+
export declare function assertOpsPosixCacheAdmission(deniedRoots: readonly string[]): void;
|
|
25
|
+
export declare function opsDispatchBarrier(ctx: Context, scope: MultiRootScopeService, exec: ToolCaller): string | undefined;
|
|
@@ -16,6 +16,7 @@ export interface SkillsForm {
|
|
|
16
16
|
value: boolean;
|
|
17
17
|
}[], revision?: number): Promise<boolean>;
|
|
18
18
|
}
|
|
19
|
+
export declare function bindSettingsForm(ctx: Context, entryId: string): SkillsForm | undefined;
|
|
19
20
|
export declare function bindSkillsForm(ctx: Context): SkillsForm | undefined;
|
|
20
21
|
export declare function clientInject(ctx: Context, services: string[], callback: (scope: Context) => void | (() => void)): void;
|
|
21
22
|
export interface NamespaceRule {
|
|
@@ -5,5 +5,9 @@ export interface ToolCaller {
|
|
|
5
5
|
readonly agent?: Agent;
|
|
6
6
|
readonly callId: string;
|
|
7
7
|
readonly name: string;
|
|
8
|
+
readonly arguments?: unknown;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
readonly parent?: unknown;
|
|
11
|
+
readonly token?: object;
|
|
8
12
|
}
|
|
9
13
|
export declare function aroundTool(ctx: Context, listener: (exec: ToolCaller, next: () => Promise<unknown>) => Promise<unknown>): void;
|
package/lib/types/compat.d.ts
CHANGED
|
@@ -57,8 +57,8 @@ export declare class DshCompatUnsupportedError extends Error {
|
|
|
57
57
|
* `./compat/` detect the shape they need STRUCTURALLY — whether a return value
|
|
58
58
|
* is a thenable, which export name a module carries — because a structural
|
|
59
59
|
* probe also survives upstream reshaping something within one release, while a
|
|
60
|
-
* version comparison does not. The release string here is for
|
|
61
|
-
* diagnostics.
|
|
60
|
+
* version comparison does not. The release string here is for installation and
|
|
61
|
+
* feature-availability gates (such as the OPS 0.2.* policy), and diagnostics.
|
|
62
62
|
*/
|
|
63
63
|
export declare class MultiRootCompatService extends Service {
|
|
64
64
|
/** The verdict this composition started under. */
|
|
@@ -4,7 +4,12 @@ declare module '@deepseek-ai/cordis' {
|
|
|
4
4
|
interface Context {
|
|
5
5
|
multiRootInstructions: {
|
|
6
6
|
knownRoots(session: object): readonly string[];
|
|
7
|
-
snapshot(agent: Agent, roots: readonly string[], target: string | undefined, signal: AbortSignal
|
|
7
|
+
snapshot(agent: Agent, roots: readonly string[], target: string | readonly string[] | undefined, signal: AbortSignal, pending?: {
|
|
8
|
+
readonly callId: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly arguments: unknown;
|
|
11
|
+
readonly parent?: unknown;
|
|
12
|
+
}): Promise<readonly CurrentRootInstruction[]>;
|
|
8
13
|
};
|
|
9
14
|
}
|
|
10
15
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Service, type Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
export interface Config {
|
|
4
|
+
readonly enabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
7
|
+
enabled: z<boolean, boolean, "defined">;
|
|
8
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
9
|
+
enabled: z<boolean, boolean, "defined">;
|
|
10
|
+
}>>, "plain">;
|
|
11
|
+
declare module '@deepseek-ai/cordis' {
|
|
12
|
+
interface Context {
|
|
13
|
+
multiRootOpsCompatibility: MultiRootOpsCompatibility;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export declare class MultiRootOpsCompatibility extends Service {
|
|
17
|
+
private readonly settingsConfig;
|
|
18
|
+
static Config: z<Schemastery.ObjectS<NoInfer<{
|
|
19
|
+
enabled: z<boolean, boolean, "defined">;
|
|
20
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
21
|
+
enabled: z<boolean, boolean, "defined">;
|
|
22
|
+
}>>, "plain">;
|
|
23
|
+
static provide: string;
|
|
24
|
+
static inject: string[];
|
|
25
|
+
constructor(ctx: Context, settingsConfig?: Config);
|
|
26
|
+
private settingsRead;
|
|
27
|
+
private currentToken;
|
|
28
|
+
private enabledNow;
|
|
29
|
+
private closing;
|
|
30
|
+
get token(): object | undefined;
|
|
31
|
+
get enabled(): boolean;
|
|
32
|
+
private sync;
|
|
33
|
+
}
|
|
34
|
+
export default MultiRootOpsCompatibility;
|
package/lib/types/registry.d.ts
CHANGED
|
@@ -121,7 +121,12 @@ export type RegistryAuthorityState = {
|
|
|
121
121
|
export interface Config {
|
|
122
122
|
/** Absolute path of the store-wide kernel lock file. */
|
|
123
123
|
readonly leasePath?: string;
|
|
124
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* Medium binding for the multi-Host authority service — REQUIRED since the
|
|
126
|
+
* single-process mode was removed (ADR-0028). Absent or empty puts the
|
|
127
|
+
* registry in the fail-closed `config-invalid` state: no lease, no domain,
|
|
128
|
+
* no grants.
|
|
129
|
+
*/
|
|
125
130
|
readonly sharedStorageRoot?: string;
|
|
126
131
|
/**
|
|
127
132
|
* Cap on STORED additional-root records per primary root (every state
|
|
@@ -281,8 +286,15 @@ export declare class MultiRootRegistry extends Service {
|
|
|
281
286
|
/** Keys already warned about a historical over-limit store (one warning each). */
|
|
282
287
|
private readonly warnedOverLimit;
|
|
283
288
|
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
289
|
+
* The canonical value each protected boundary resolved to the FIRST time it
|
|
290
|
+
* could be computed, keyed by boundary kind. Never re-pinned: a later
|
|
291
|
+
* rename or symlink swap of the DSH home (or of the lease directory) must
|
|
292
|
+
* not drop the boundary the registration rules were enforced under.
|
|
293
|
+
*/
|
|
294
|
+
private readonly pinnedProtectedPaths;
|
|
295
|
+
/**
|
|
296
|
+
* @param ctx - the host context; `storage` and `multiRootScope` are injected.
|
|
297
|
+
* @param config - the patch row's `sharedStorageRoot`, `leasePath`, and `maxAdditionalRoots`.
|
|
286
298
|
*/
|
|
287
299
|
constructor(ctx: Context, config?: Config);
|
|
288
300
|
/**
|
|
@@ -379,6 +391,44 @@ export declare class MultiRootRegistry extends Service {
|
|
|
379
391
|
*/
|
|
380
392
|
withOperation<T>(policy: SandboxExecutionPolicy, kind: RegistryOperationKind, body: (operation: RegistryOperation) => T | Promise<T>): Promise<T>;
|
|
381
393
|
withPrimaryOperation<T>(policy: SandboxExecutionPolicy, body: () => T): T;
|
|
394
|
+
/**
|
|
395
|
+
* The spellings one protected boundary contributes: the configured path,
|
|
396
|
+
* its current canonical resolution, and the canonical value pinned the
|
|
397
|
+
* first time it resolved — never re-pinned, so a later rename or symlink
|
|
398
|
+
* swap of the protected directory cannot drop the boundary the
|
|
399
|
+
* registration rules were enforced under. The list is deduplicated by
|
|
400
|
+
* {@link samePath}.
|
|
401
|
+
*/
|
|
402
|
+
private boundarySpellings;
|
|
403
|
+
/**
|
|
404
|
+
* The best-known protected-boundary set, plus whether it is COMPLETE.
|
|
405
|
+
*
|
|
406
|
+
* The set comes from trusted host configuration, never from a panel or
|
|
407
|
+
* shell claim: the scope row's `dshHome`, the physical medium
|
|
408
|
+
* `storeIdentity` bound, and the lease directory beside it.
|
|
409
|
+
* `complete` is false — and only NEW grants may then be refused — when a
|
|
410
|
+
* boundary cannot be proven: an invalid `dshHome` config, a configured
|
|
411
|
+
* home that is not a directory right now, or a medium that was never bound. Stored classification always consumes whatever IS known
|
|
412
|
+
* (pinned values included), so an unknown boundary never weakens the
|
|
413
|
+
* revalidation of existing records.
|
|
414
|
+
*/
|
|
415
|
+
private protectedBoundarySet;
|
|
416
|
+
/**
|
|
417
|
+
* The protected DSH directories this Host can prove right now, or
|
|
418
|
+
* `undefined` when the set cannot be proven. `undefined` blocks every NEW
|
|
419
|
+
* grant; it never weakens the classification of stored records.
|
|
420
|
+
*/
|
|
421
|
+
private protectedPaths;
|
|
422
|
+
/**
|
|
423
|
+
* Every protected entry this Host can prove — used wherever a partial set
|
|
424
|
+
* must still protect stored records and received snapshots.
|
|
425
|
+
*/
|
|
426
|
+
private knownProtectedPaths;
|
|
427
|
+
/**
|
|
428
|
+
* The one refusal shared by the owner mutation path and the follower
|
|
429
|
+
* pre-check: the protected set cannot be proven, so no new grant is safe.
|
|
430
|
+
*/
|
|
431
|
+
private static protectedBoundaryUnknown;
|
|
382
432
|
/**
|
|
383
433
|
* Registers one additional root.
|
|
384
434
|
* @param primaryRoot - the session workspace root the root belongs to.
|
|
@@ -463,7 +513,7 @@ export declare class MultiRootRegistry extends Service {
|
|
|
463
513
|
recheck(primaryRoot: string): Promise<readonly RootStatus[]>;
|
|
464
514
|
/**
|
|
465
515
|
* Observe registry changes.
|
|
466
|
-
* @param listener - called with the
|
|
516
|
+
* @param listener - called with the Registry key (`primaryKey()`, case-folded on Windows) after each durable change.
|
|
467
517
|
* @returns the disposer that stops observing.
|
|
468
518
|
*/
|
|
469
519
|
onChange(listener: (primaryRoot: string) => void): () => void;
|
|
@@ -495,10 +545,17 @@ export declare class MultiRootRegistry extends Service {
|
|
|
495
545
|
*/
|
|
496
546
|
private statusesOf;
|
|
497
547
|
/**
|
|
498
|
-
* The stored record set of one key,
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
* the
|
|
548
|
+
* The stored record set of one key: `{ record, migrated: false }` when the
|
|
549
|
+
* spelling key holds it; `{ record, migrated: true }` when only the legacy
|
|
550
|
+
* CANONICAL key does — stores written before the upstream primary spelling
|
|
551
|
+
* became the key (v0.1.14 and earlier). The fallback follows the CURRENT
|
|
552
|
+
* resolution ONLY for such a not-yet-migrated store; the first serialized
|
|
553
|
+
* access copies the record forward under the spelling key (see
|
|
554
|
+
* {@link reclassify}), after which resolution can never re-key a grant.
|
|
555
|
+
* `undefined` when there is no record (or when the store itself could not
|
|
556
|
+
* be read: an unusable store reads as "nothing registered" so reads stay
|
|
557
|
+
* answerable and the surfaces can explain the situation, while every write
|
|
558
|
+
* fails loudly in `requireTable()`).
|
|
502
559
|
*/
|
|
503
560
|
private lookupRecords;
|
|
504
561
|
/**
|
|
@@ -562,6 +619,8 @@ export declare class MultiRootRegistry extends Service {
|
|
|
562
619
|
private commit;
|
|
563
620
|
/** Deliver one key's notifications now, or collect them inside a commit. */
|
|
564
621
|
private deliverNotifications;
|
|
622
|
+
/** Narrow owner rows for this Host, identically for projection and admission. */
|
|
623
|
+
private localSnapshotRoots;
|
|
565
624
|
private applySnapshot;
|
|
566
625
|
private remoteUnavailable;
|
|
567
626
|
/**
|
|
@@ -8,8 +8,10 @@ declare module '@deepseek-ai/cordis' {
|
|
|
8
8
|
}
|
|
9
9
|
export interface ReviewExecution {
|
|
10
10
|
readonly agent?: Agent;
|
|
11
|
+
readonly callId?: string;
|
|
11
12
|
readonly name: string;
|
|
12
13
|
readonly arguments: unknown;
|
|
14
|
+
readonly parent?: unknown;
|
|
13
15
|
}
|
|
14
16
|
export interface ReviewContext {
|
|
15
17
|
readonly schemaVersion: 1;
|