@dsh-electron/dsh-plugin-multi-root-workspace 0.1.13 → 0.1.14
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 +17 -1
- package/CHANGELOG.md +17 -1
- package/README.en.md +8 -8
- package/README.md +8 -8
- package/detail/DETAIL.en.md +1 -0
- package/detail/DETAIL.md +1 -0
- package/detail/preview.svg +1 -0
- package/detail/preview.zh.svg +1 -0
- package/lib/client.js +392 -63
- package/lib/client.js.map +1 -1
- package/lib/{command-B9855H7y.js → command-Dcz6nULo.js} +25 -3
- package/lib/command.js +1 -1
- package/lib/{compat-Bg2HFVMX.js → compat-veDqCOoa.js} +3 -1
- package/lib/compat.js +1 -1
- package/lib/{fs-CfzJq2wd.js → fs-Uws0ZpmV.js} +38 -0
- package/lib/fs.js +1 -1
- package/lib/index.js +4 -4
- package/lib/{native-win32-2waCRkPI.js → native-win32-CRNXr11U.js} +2 -1
- package/lib/{protocol-CJOvAvOS.js → protocol-CnR1KTXy.js} +49 -7
- package/lib/{registry-Bv431TfO.js → registry-DR_sMuvS.js} +3 -3
- package/lib/{registry-lease-win32-DVTq9d4D.js → registry-lease-win32-DDO-c7ig.js} +2 -1
- package/lib/registry.js +2 -2
- package/lib/types/client/RootSwitcher.d.ts +2 -0
- package/lib/types/client/auto-review-settings.d.ts +18 -0
- package/lib/types/client/files-tree/FilesTree.d.ts +4 -1
- package/lib/types/client/files-tree/locales.d.ts +1 -1
- package/lib/types/client/locales.d.ts +12 -0
- package/lib/types/client/open-in-app/locales.d.ts +1 -1
- package/lib/types/client/skills-settings.d.ts +12 -0
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/compat/auto-review-client.d.ts +58 -0
- package/lib/types/compat/connection-rpc.d.ts +12 -0
- package/lib/types/compat/dsh-version.d.ts +1 -1
- package/lib/types/compat/files-tree.d.ts +36 -0
- package/lib/types/compat/fs-patch.d.ts +6 -0
- package/lib/types/compat/koffi.d.ts +2 -0
- package/lib/types/fs.d.ts +3 -1
- package/locale/en.json +7 -0
- package/locale/zh.json +7 -0
- package/package.json +89 -82
- package/src/auto-review/README.en.md +1 -1
- package/src/auto-review/README.md +1 -1
package/lib/client.js
CHANGED
|
@@ -123,6 +123,48 @@ window.__ModuleLoader__.load({
|
|
|
123
123
|
return typeof count === "number" && count > 0;
|
|
124
124
|
}
|
|
125
125
|
//#endregion
|
|
126
|
+
//#region src/compat/files-tree.ts
|
|
127
|
+
function nativeTreeRenderer(value) {
|
|
128
|
+
return typeof value === "function" ? value : void 0;
|
|
129
|
+
}
|
|
130
|
+
/** The factory consumes absolute, slash-separated keys and already-localized errors. */
|
|
131
|
+
function nativeTreeInput(state, failureLine, toggle, open) {
|
|
132
|
+
const root = state.root.replace(/[/\\]+$/, "");
|
|
133
|
+
const keyOf = (path) => path === state.root ? root : path;
|
|
134
|
+
const entries = [];
|
|
135
|
+
const directories = {};
|
|
136
|
+
for (const path of state.expanded) directories[keyOf(path)] = { loading: true };
|
|
137
|
+
for (const [path, level] of Object.entries(state.levels)) {
|
|
138
|
+
const key = keyOf(path);
|
|
139
|
+
if (level.kind === "loading") directories[key] = { loading: true };
|
|
140
|
+
else if (level.kind === "failed") directories[key] = { failure: failureLine(level.failure) };
|
|
141
|
+
else {
|
|
142
|
+
const status = {};
|
|
143
|
+
if (level.failure !== void 0) status.failure = failureLine(level.failure);
|
|
144
|
+
if (level.level.truncated) status.truncated = true;
|
|
145
|
+
directories[key] = status;
|
|
146
|
+
for (const entry of level.level.entries) entries.push({
|
|
147
|
+
path: `${path.replace(/[/\\]+$/, "")}/${entry.name}`,
|
|
148
|
+
name: entry.name,
|
|
149
|
+
meta: { kind: entry.type }
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
root,
|
|
155
|
+
entries,
|
|
156
|
+
directories,
|
|
157
|
+
expanded: state.expanded.map(keyOf),
|
|
158
|
+
onToggle: (entry) => {
|
|
159
|
+
const parent = entry.path.slice(0, entry.path.lastIndexOf("/"));
|
|
160
|
+
toggle(parent === root ? state.root : parent, entry.path);
|
|
161
|
+
},
|
|
162
|
+
onOpen: (entry) => {
|
|
163
|
+
open(entry.path);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
//#endregion
|
|
126
168
|
//#region node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/core/util.js
|
|
127
169
|
function getEnumValues(entries) {
|
|
128
170
|
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
@@ -5545,6 +5587,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5545
5587
|
"skills.globalEnable": "启用附属根 Skills",
|
|
5546
5588
|
"skills.globalHint": "控制所有附属目录的 Skill 发现与新调用;保留每个目录的独立选择。",
|
|
5547
5589
|
"skills.settingsFailed": "设置保存失败,请重试。",
|
|
5590
|
+
"autoReview.title": "多根 Auto Review",
|
|
5591
|
+
"autoReview.experimental": "实验性",
|
|
5592
|
+
"autoReview.hint": "为附加根保留审核上下文并接管 Auto 审查;与插件管理页同名 Loader 行开关等价,默认关闭,仅适配 DSH 0.2.1-rc.2。",
|
|
5593
|
+
"autoReview.loadFailed": "无法读取插件状态。",
|
|
5594
|
+
"autoReview.restartRequired": "更改将在重启后生效。",
|
|
5595
|
+
"autoReview.settingsFailed": "设置保存失败,请重试。",
|
|
5548
5596
|
"skills.userOnly": "仅用户调用",
|
|
5549
5597
|
"panel.skills": "目录技能",
|
|
5550
5598
|
"panel.skillsEnabled": "此目录技能已启用,点击停用",
|
|
@@ -5632,6 +5680,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5632
5680
|
"skills.globalEnable": "Enable additional-root Skills",
|
|
5633
5681
|
"skills.globalHint": "Controls discovery and new invocations for all additional folders, preserving each folder’s choice.",
|
|
5634
5682
|
"skills.settingsFailed": "Could not save settings. Please try again.",
|
|
5683
|
+
"autoReview.title": "Multi-root Auto Review",
|
|
5684
|
+
"autoReview.experimental": "Experimental",
|
|
5685
|
+
"autoReview.hint": "Preserves multi-root context for Auto review and takes over the reviewer; equivalent to the same Loader row switch in the Plugin Manager. Off by default; adapted to DSH 0.2.1-rc.2 only.",
|
|
5686
|
+
"autoReview.loadFailed": "Could not read plugin state.",
|
|
5687
|
+
"autoReview.restartRequired": "The change takes effect after restart.",
|
|
5688
|
+
"autoReview.settingsFailed": "Could not save settings. Please try again.",
|
|
5635
5689
|
"skills.userOnly": "User invocation only",
|
|
5636
5690
|
"panel.skills": "Folder skills",
|
|
5637
5691
|
"panel.skillsEnabled": "Skills enabled for this folder. Click to disable.",
|
|
@@ -5928,6 +5982,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5928
5982
|
display: none;
|
|
5929
5983
|
}
|
|
5930
5984
|
|
|
5985
|
+
/* Newer Files pages place the navigator beside the header instead of
|
|
5986
|
+
wrapping both in data-files-root. Target the page without hiding the
|
|
5987
|
+
portaled replacement or any of its rows. */
|
|
5988
|
+
[data-files-page]:has(.mrfw-fileLauncher) [data-files-path]:not([data-files-entry]) { order: -2; }
|
|
5989
|
+
[data-files-page]:has(.mrfw-rootSwitcher) [data-files-path]:not([data-files-entry]) { display: none; }
|
|
5990
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-files-content],
|
|
5991
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-files-reload] { display: none; }
|
|
5992
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-slot="sidebar.right.tab.files.actions"] > *:has([data-open-target="directory"]:not(.mrfw-openSplit)),
|
|
5993
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-open-target="directory"]:not(.mrfw-openSplit) { display: none; }
|
|
5994
|
+
|
|
5931
5995
|
/* While the switcher names an additional root, the native open-in-app split
|
|
5932
5996
|
button hides too: its slot props carry the pane's primary root, so it
|
|
5933
5997
|
would always open the primary root no matter what the switcher selected.
|
|
@@ -6360,6 +6424,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6360
6424
|
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
6361
6425
|
}
|
|
6362
6426
|
.mrfw-skillsSettingsText { min-width: 0; }
|
|
6427
|
+
.mrfw-settingsTitleRow {
|
|
6428
|
+
display: flex;
|
|
6429
|
+
align-items: center;
|
|
6430
|
+
gap: 8px;
|
|
6431
|
+
}
|
|
6363
6432
|
.mrfw-skillsSettingsTitle { font-size: 14px; line-height: 20px; }
|
|
6364
6433
|
.mrfw-skillsSettingsDescription {
|
|
6365
6434
|
margin-top: 4px;
|
|
@@ -6842,90 +6911,345 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6842
6911
|
});
|
|
6843
6912
|
}
|
|
6844
6913
|
//#endregion
|
|
6914
|
+
//#region src/compat/auto-review-client.ts
|
|
6915
|
+
/** The module specifier `cordis.patch.yml` gives the optional row. */
|
|
6916
|
+
const AUTO_REVIEW_MODULE = "@dsh-electron/dsh-plugin-multi-root-workspace/auto-review";
|
|
6917
|
+
var AutoReviewSettingsForm = class {
|
|
6918
|
+
snapshot = { status: "unavailable" };
|
|
6919
|
+
listeners = /* @__PURE__ */ new Set();
|
|
6920
|
+
manager;
|
|
6921
|
+
stopEvents;
|
|
6922
|
+
epoch = 0;
|
|
6923
|
+
refreshSeq = 0;
|
|
6924
|
+
getSnapshot() {
|
|
6925
|
+
return this.snapshot;
|
|
6926
|
+
}
|
|
6927
|
+
subscribe(listener) {
|
|
6928
|
+
this.listeners.add(listener);
|
|
6929
|
+
return () => {
|
|
6930
|
+
this.listeners.delete(listener);
|
|
6931
|
+
};
|
|
6932
|
+
}
|
|
6933
|
+
publish(next) {
|
|
6934
|
+
this.snapshot = next;
|
|
6935
|
+
for (const listener of [...this.listeners]) listener();
|
|
6936
|
+
}
|
|
6937
|
+
attach(manager, remote) {
|
|
6938
|
+
this.detach();
|
|
6939
|
+
this.manager = manager;
|
|
6940
|
+
this.epoch++;
|
|
6941
|
+
this.publish({ status: "loading" });
|
|
6942
|
+
if (remote !== void 0) try {
|
|
6943
|
+
this.stopEvents = remote.$on("plugin-manager/changed", () => {
|
|
6944
|
+
this.refresh();
|
|
6945
|
+
});
|
|
6946
|
+
} catch {
|
|
6947
|
+
this.stopEvents = void 0;
|
|
6948
|
+
}
|
|
6949
|
+
this.refresh();
|
|
6950
|
+
}
|
|
6951
|
+
detach() {
|
|
6952
|
+
this.stopEvents?.();
|
|
6953
|
+
this.stopEvents = void 0;
|
|
6954
|
+
this.manager = void 0;
|
|
6955
|
+
this.epoch++;
|
|
6956
|
+
this.publish({ status: "unavailable" });
|
|
6957
|
+
}
|
|
6958
|
+
async refresh() {
|
|
6959
|
+
const manager = this.manager;
|
|
6960
|
+
const epoch = this.epoch;
|
|
6961
|
+
const seq = ++this.refreshSeq;
|
|
6962
|
+
if (manager === void 0) return;
|
|
6963
|
+
const result = await manager.listPlugins();
|
|
6964
|
+
if (manager !== this.manager || epoch !== this.epoch || seq !== this.refreshSeq) return;
|
|
6965
|
+
if (!result.ok) {
|
|
6966
|
+
this.publish({ status: "error" });
|
|
6967
|
+
return;
|
|
6968
|
+
}
|
|
6969
|
+
const entry = result.value.find((item) => item.moduleName === AUTO_REVIEW_MODULE);
|
|
6970
|
+
this.publish(entry === void 0 ? { status: "ready" } : {
|
|
6971
|
+
status: "ready",
|
|
6972
|
+
row: {
|
|
6973
|
+
entryId: entry.entryId,
|
|
6974
|
+
enabled: entry.enabled,
|
|
6975
|
+
writable: entry.readOnlyReason === void 0,
|
|
6976
|
+
...entry.diagnostic === void 0 ? {} : { diagnostic: entry.diagnostic }
|
|
6977
|
+
}
|
|
6978
|
+
});
|
|
6979
|
+
}
|
|
6980
|
+
async setEnabled(enabled) {
|
|
6981
|
+
const manager = this.manager;
|
|
6982
|
+
const row = this.snapshot.status === "ready" ? this.snapshot.row : void 0;
|
|
6983
|
+
if (manager === void 0 || row === void 0) return "failed";
|
|
6984
|
+
const result = await manager.setPluginEnabled(row.entryId, enabled);
|
|
6985
|
+
await this.refresh();
|
|
6986
|
+
if (!result.ok) return "failed";
|
|
6987
|
+
const application = result.value.application;
|
|
6988
|
+
return application === "applied" || application === "restart-required" ? application : "failed";
|
|
6989
|
+
}
|
|
6990
|
+
};
|
|
6991
|
+
/**
|
|
6992
|
+
* Create the card's Auto Review handle and attach it when the host's
|
|
6993
|
+
* `pluginManager` namespace arrives. The returned form exists immediately with
|
|
6994
|
+
* status `unavailable` and publishes on every attach/detach/read, so callers
|
|
6995
|
+
* only need `subscribe` — no separate availability callback.
|
|
6996
|
+
* @param ctx - the client root context.
|
|
6997
|
+
* @returns the stable form the settings row renders.
|
|
6998
|
+
*/
|
|
6999
|
+
function installAutoReviewSettings(ctx) {
|
|
7000
|
+
const form = new AutoReviewSettingsForm();
|
|
7001
|
+
clientInject(ctx, ["remote.pluginManager"], (scope) => {
|
|
7002
|
+
const manager = scope.get("remote.pluginManager");
|
|
7003
|
+
if (manager === void 0) return;
|
|
7004
|
+
const remote = scope.get("remote");
|
|
7005
|
+
form.attach(manager, remote);
|
|
7006
|
+
return () => {
|
|
7007
|
+
form.detach();
|
|
7008
|
+
};
|
|
7009
|
+
});
|
|
7010
|
+
return form;
|
|
7011
|
+
}
|
|
7012
|
+
//#endregion
|
|
7013
|
+
//#region src/client/auto-review-settings.tsx
|
|
7014
|
+
/**
|
|
7015
|
+
* Full-opacity hold for the card's message toasts — the same window upstream
|
|
7016
|
+
* gives a refusal banner, since these strings name what broke rather than
|
|
7017
|
+
* reporting a one-line limit.
|
|
7018
|
+
*/
|
|
7019
|
+
const TOAST_HOLD_MS = 8e3;
|
|
7020
|
+
/**
|
|
7021
|
+
* The optional Auto Review row of the plugin settings card.
|
|
7022
|
+
*
|
|
7023
|
+
* Its switch is the Loader row's own enablement — the same write the Plugin
|
|
7024
|
+
* Manager's row switch performs — so the card can never disagree with the row
|
|
7025
|
+
* list about whether the companion is on. Feedback is a transient `Toast`
|
|
7026
|
+
* banner, never inline text: state-driven messages (a failed read, an entry
|
|
7027
|
+
* diagnostic) fire on entry and clear when their source resolves, while write
|
|
7028
|
+
* outcomes report once and fade. The row stays hidden entirely on hosts
|
|
7029
|
+
* without the `pluginManager` namespace or when the composition does not list
|
|
7030
|
+
* the optional entry.
|
|
7031
|
+
*/
|
|
7032
|
+
function AutoReviewSettingsCard({ form, t }) {
|
|
7033
|
+
const snapshot = (0, react.useSyncExternalStore)((listener) => form.subscribe(listener), () => form.getSnapshot());
|
|
7034
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
7035
|
+
const mounted = (0, react.useRef)(true);
|
|
7036
|
+
const toastSeq = (0, react.useRef)(0);
|
|
7037
|
+
const [toast, setToast] = (0, react.useState)(null);
|
|
7038
|
+
(0, react.useEffect)(() => {
|
|
7039
|
+
mounted.current = true;
|
|
7040
|
+
return () => {
|
|
7041
|
+
mounted.current = false;
|
|
7042
|
+
};
|
|
7043
|
+
}, []);
|
|
7044
|
+
const showToast = (0, react.useCallback)((kind, text) => {
|
|
7045
|
+
toastSeq.current += 1;
|
|
7046
|
+
setToast({
|
|
7047
|
+
seq: toastSeq.current,
|
|
7048
|
+
kind,
|
|
7049
|
+
text
|
|
7050
|
+
});
|
|
7051
|
+
}, []);
|
|
7052
|
+
const dismissToast = (0, react.useCallback)((kind) => {
|
|
7053
|
+
setToast((current) => current?.kind === kind ? null : current);
|
|
7054
|
+
}, []);
|
|
7055
|
+
const status = snapshot.status;
|
|
7056
|
+
const diagnostic = status === "ready" ? snapshot.row?.diagnostic : void 0;
|
|
7057
|
+
(0, react.useEffect)(() => {
|
|
7058
|
+
if (status === "error") showToast("load", t("autoReview.loadFailed"));
|
|
7059
|
+
else dismissToast("load");
|
|
7060
|
+
}, [
|
|
7061
|
+
status,
|
|
7062
|
+
t,
|
|
7063
|
+
showToast,
|
|
7064
|
+
dismissToast
|
|
7065
|
+
]);
|
|
7066
|
+
(0, react.useEffect)(() => {
|
|
7067
|
+
if (diagnostic !== void 0 && diagnostic !== "") showToast("diagnostic", diagnostic);
|
|
7068
|
+
else dismissToast("diagnostic");
|
|
7069
|
+
}, [
|
|
7070
|
+
diagnostic,
|
|
7071
|
+
showToast,
|
|
7072
|
+
dismissToast
|
|
7073
|
+
]);
|
|
7074
|
+
if (status === "unavailable") return null;
|
|
7075
|
+
const row = status === "ready" ? snapshot.row : void 0;
|
|
7076
|
+
if (status === "ready" && row === void 0) return null;
|
|
7077
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7078
|
+
className: "mrfw-skillsSettings",
|
|
7079
|
+
children: [
|
|
7080
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7081
|
+
className: "mrfw-skillsSettingsText",
|
|
7082
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7083
|
+
className: "mrfw-settingsTitleRow",
|
|
7084
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7085
|
+
className: "mrfw-skillsSettingsTitle",
|
|
7086
|
+
children: t("autoReview.title")
|
|
7087
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
7088
|
+
tone: "info",
|
|
7089
|
+
children: t("autoReview.experimental")
|
|
7090
|
+
})]
|
|
7091
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7092
|
+
className: "mrfw-skillsSettingsDescription",
|
|
7093
|
+
children: t("autoReview.hint")
|
|
7094
|
+
})]
|
|
7095
|
+
}),
|
|
7096
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
7097
|
+
label: t("autoReview.title"),
|
|
7098
|
+
checked: row?.enabled ?? false,
|
|
7099
|
+
disabled: busy || row?.writable !== true,
|
|
7100
|
+
onChange: (enabled) => {
|
|
7101
|
+
setBusy(true);
|
|
7102
|
+
form.setEnabled(enabled).then((result) => {
|
|
7103
|
+
if (!mounted.current) return;
|
|
7104
|
+
if (result === "restart-required") showToast("write", t("autoReview.restartRequired"));
|
|
7105
|
+
else if (result === "failed") showToast("write", t("autoReview.settingsFailed"));
|
|
7106
|
+
}).catch(() => {
|
|
7107
|
+
if (mounted.current) showToast("write", t("autoReview.settingsFailed"));
|
|
7108
|
+
}).finally(() => {
|
|
7109
|
+
if (mounted.current) setBusy(false);
|
|
7110
|
+
});
|
|
7111
|
+
}
|
|
7112
|
+
}),
|
|
7113
|
+
toast === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
7114
|
+
text: toast.text,
|
|
7115
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
|
|
7116
|
+
holdMs: TOAST_HOLD_MS,
|
|
7117
|
+
onDone: () => {
|
|
7118
|
+
setToast(null);
|
|
7119
|
+
}
|
|
7120
|
+
}, toast.seq)
|
|
7121
|
+
]
|
|
7122
|
+
});
|
|
7123
|
+
}
|
|
7124
|
+
//#endregion
|
|
6845
7125
|
//#region src/client/skills-settings.tsx
|
|
6846
7126
|
const BUNDLE_KEY = "@dsh-electron/dsh-plugin-multi-root-workspace";
|
|
6847
7127
|
function SkillsSettingsCard({ form, t }) {
|
|
6848
7128
|
const snapshot = (0, react.useSyncExternalStore)((listener) => form.subscribe(listener), () => form.getSnapshot());
|
|
6849
|
-
const [busy, setBusy] = (0, react.useState)(false)
|
|
7129
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
6850
7130
|
const mounted = (0, react.useRef)(true);
|
|
7131
|
+
const toastSeq = (0, react.useRef)(0);
|
|
7132
|
+
const [toast, setToast] = (0, react.useState)(null);
|
|
6851
7133
|
(0, react.useEffect)(() => {
|
|
6852
7134
|
mounted.current = true;
|
|
6853
7135
|
return () => {
|
|
6854
7136
|
mounted.current = false;
|
|
6855
7137
|
};
|
|
6856
7138
|
}, []);
|
|
7139
|
+
const showToast = (0, react.useCallback)((text) => {
|
|
7140
|
+
toastSeq.current += 1;
|
|
7141
|
+
setToast({
|
|
7142
|
+
seq: toastSeq.current,
|
|
7143
|
+
text
|
|
7144
|
+
});
|
|
7145
|
+
}, []);
|
|
6857
7146
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6858
7147
|
className: "mrfw-skillsSettings",
|
|
6859
|
-
children: [
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7148
|
+
children: [
|
|
7149
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7150
|
+
className: "mrfw-skillsSettingsText",
|
|
7151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6863
7152
|
className: "mrfw-skillsSettingsTitle",
|
|
6864
7153
|
children: t("skills.globalEnable")
|
|
6865
|
-
}),
|
|
6866
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7154
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6867
7155
|
className: "mrfw-skillsSettingsDescription",
|
|
6868
7156
|
children: t("skills.globalHint")
|
|
6869
|
-
})
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
}
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
})
|
|
6893
|
-
|
|
6894
|
-
|
|
7157
|
+
})]
|
|
7158
|
+
}),
|
|
7159
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
7160
|
+
label: t("skills.globalEnable"),
|
|
7161
|
+
checked: snapshot.value?.enabled ?? true,
|
|
7162
|
+
disabled: busy || snapshot.status !== "ready" || !snapshot.writable,
|
|
7163
|
+
onChange: (enabled) => {
|
|
7164
|
+
setBusy(true);
|
|
7165
|
+
form.mutate([{
|
|
7166
|
+
op: "set",
|
|
7167
|
+
path: ["enabled"],
|
|
7168
|
+
value: enabled
|
|
7169
|
+
}], snapshot.revision).then((ok) => {
|
|
7170
|
+
if (mounted.current && !ok) showToast(t("skills.settingsFailed"));
|
|
7171
|
+
}).catch(() => {
|
|
7172
|
+
if (mounted.current) showToast(t("skills.settingsFailed"));
|
|
7173
|
+
}).finally(() => {
|
|
7174
|
+
if (mounted.current) setBusy(false);
|
|
7175
|
+
});
|
|
7176
|
+
}
|
|
7177
|
+
}),
|
|
7178
|
+
toast === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
7179
|
+
text: toast.text,
|
|
7180
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
|
|
7181
|
+
holdMs: 8e3,
|
|
7182
|
+
onDone: () => {
|
|
7183
|
+
setToast(null);
|
|
7184
|
+
}
|
|
7185
|
+
}, toast.seq)
|
|
7186
|
+
]
|
|
6895
7187
|
});
|
|
6896
7188
|
}
|
|
7189
|
+
/**
|
|
7190
|
+
* The bundle's one `plugins.bundle.config` cell: every plugin-level switch the
|
|
7191
|
+
* package offers, in display order. Each row owns its own form and write path —
|
|
7192
|
+
* Skills through its settings namespace, Auto Review through the Plugin
|
|
7193
|
+
* Manager's Loader-row enablement — so one cell never serializes their state.
|
|
7194
|
+
*/
|
|
7195
|
+
function BundleSettingsCard({ form, autoReviewForm, t }) {
|
|
7196
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [form !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkillsSettingsCard, {
|
|
7197
|
+
form,
|
|
7198
|
+
t
|
|
7199
|
+
}) : null, autoReviewForm !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoReviewSettingsCard, {
|
|
7200
|
+
form: autoReviewForm,
|
|
7201
|
+
t
|
|
7202
|
+
}) : null] });
|
|
7203
|
+
}
|
|
6897
7204
|
function installSkillsSettingsCard(ctx, t) {
|
|
6898
|
-
let
|
|
7205
|
+
let currentSkills;
|
|
7206
|
+
let currentAutoReview = false;
|
|
6899
7207
|
let stop;
|
|
6900
7208
|
const candidates = /* @__PURE__ */ new Map();
|
|
6901
7209
|
const update = () => {
|
|
6902
|
-
const
|
|
6903
|
-
|
|
7210
|
+
const skillsForm = [...candidates.entries()].sort(([a], [b]) => Number(b.get("configForms") !== void 0) - Number(a.get("configForms") !== void 0))[0]?.[1];
|
|
7211
|
+
const autoSnapshot = autoForm.getSnapshot();
|
|
7212
|
+
const autoAvailable = autoSnapshot.status === "loading" || autoSnapshot.status === "error" || autoSnapshot.status === "ready" && autoSnapshot.row !== void 0;
|
|
7213
|
+
if (skillsForm === void 0 && !autoAvailable) {
|
|
7214
|
+
if (currentSkills !== void 0 || currentAutoReview) {
|
|
7215
|
+
stop?.();
|
|
7216
|
+
stop = void 0;
|
|
7217
|
+
currentSkills = void 0;
|
|
7218
|
+
currentAutoReview = false;
|
|
7219
|
+
}
|
|
7220
|
+
return;
|
|
7221
|
+
}
|
|
7222
|
+
if (currentSkills === skillsForm && currentAutoReview === autoAvailable) return;
|
|
7223
|
+
const slots = ctx.slots;
|
|
7224
|
+
if (slots === void 0) return;
|
|
6904
7225
|
stop?.();
|
|
6905
7226
|
stop = void 0;
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
const [
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
name: "settings.plugin.item",
|
|
6912
|
-
key: "multi-root-skills",
|
|
7227
|
+
currentSkills = skillsForm;
|
|
7228
|
+
currentAutoReview = autoAvailable;
|
|
7229
|
+
const disposers = [slots.inject("plugins.bundle.config", () => slots.register({
|
|
7230
|
+
name: "plugins.bundle.config",
|
|
7231
|
+
key: BUNDLE_KEY,
|
|
6913
7232
|
inject: () => ({
|
|
6914
|
-
form,
|
|
7233
|
+
form: skillsForm,
|
|
7234
|
+
autoReviewForm: autoForm,
|
|
6915
7235
|
t
|
|
6916
7236
|
})
|
|
6917
|
-
},
|
|
6918
|
-
|
|
6919
|
-
|
|
7237
|
+
}, BundleSettingsCard))];
|
|
7238
|
+
if (skillsForm !== void 0) disposers.push(slots.inject("settings.plugin.item", () => slots.register({
|
|
7239
|
+
name: "settings.plugin.item",
|
|
7240
|
+
key: "multi-root-skills",
|
|
6920
7241
|
inject: () => ({
|
|
6921
|
-
form,
|
|
7242
|
+
form: skillsForm,
|
|
6922
7243
|
t
|
|
6923
7244
|
})
|
|
6924
|
-
}, SkillsSettingsCard))
|
|
7245
|
+
}, SkillsSettingsCard)));
|
|
6925
7246
|
stop = () => {
|
|
6926
7247
|
for (const dispose of disposers) dispose();
|
|
6927
7248
|
};
|
|
6928
7249
|
};
|
|
7250
|
+
const autoForm = installAutoReviewSettings(ctx);
|
|
7251
|
+
const stopAutoWatch = autoForm.subscribe(update);
|
|
7252
|
+
update();
|
|
6929
7253
|
for (const service of ["settingsScope", "configForms"]) clientInject(ctx, [service], (scope) => {
|
|
6930
7254
|
const form = bindSkillsForm(scope);
|
|
6931
7255
|
if (form === void 0) return;
|
|
@@ -6938,6 +7262,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6938
7262
|
});
|
|
6939
7263
|
ctx.effect(() => () => {
|
|
6940
7264
|
stop?.();
|
|
7265
|
+
stopAutoWatch();
|
|
6941
7266
|
candidates.clear();
|
|
6942
7267
|
});
|
|
6943
7268
|
}
|
|
@@ -7004,7 +7329,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7004
7329
|
const IconAccessReadOnly = maybeIcon(["PermissionIconReadOnlyRegular", "IconReadOnlyRegular"]);
|
|
7005
7330
|
const IconAccessInherit = maybeIcon(["IconWorkspaceTreeOutline16", "IconWorkspaceTreeOutlineRegular"]);
|
|
7006
7331
|
//#endregion
|
|
7007
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-typert-protocol@0.2.2-
|
|
7332
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-typert-protocol@0.2.2-rc.1_@deepseek-ai+cordis@4.1.0/node_modules/@deepseek-ai/dsh-typert-protocol/lib/index.js
|
|
7008
7333
|
/** The one Remote failure class shared by owners, the Gateway, and consumers. */
|
|
7009
7334
|
/**
|
|
7010
7335
|
* One Remote call failure: a real Error carrying its stable code and typed
|
|
@@ -7514,7 +7839,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7514
7839
|
return n;
|
|
7515
7840
|
}
|
|
7516
7841
|
//#endregion
|
|
7517
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.2-
|
|
7842
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.2-rc.1_@deepseek-ai+cordis@4.1.0/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
|
|
7518
7843
|
/**
|
|
7519
7844
|
* The `dsh-resource://file/…` address grammar: how a file is named across the
|
|
7520
7845
|
* Sidebar and the resource model, built and parsed without touching a
|
|
@@ -7760,7 +8085,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7760
8085
|
* has opened under it — the upstream body's scroll, seed, and render logic
|
|
7761
8086
|
* verbatim, with the root arriving as a prop instead of `useSessions(cwd)`.
|
|
7762
8087
|
*/
|
|
7763
|
-
function FilesTree({ tabId, sessionId, root, signal, useStore, actions, start, toggle, onOpen, t }) {
|
|
8088
|
+
function FilesTree({ tabId, sessionId, root, signal, useStore, actions, start, toggle, onOpen, t, nativeTree }) {
|
|
7764
8089
|
const state = useStore((store) => store.byTab[tabId]);
|
|
7765
8090
|
const bodyRef = (0, react.useRef)(null);
|
|
7766
8091
|
const scrollTopRef = (0, react.useRef)(0);
|
|
@@ -7801,19 +8126,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7801
8126
|
},
|
|
7802
8127
|
t
|
|
7803
8128
|
};
|
|
8129
|
+
const legacy = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
8130
|
+
className: css$1.level,
|
|
8131
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Level, {
|
|
8132
|
+
path: state.root,
|
|
8133
|
+
tree
|
|
8134
|
+
})
|
|
8135
|
+
});
|
|
8136
|
+
const content = nativeTree === void 0 ? legacy : nativeTree("sidebar.files.tree", nativeTreeInput(state, (failure) => failureLine(t, failure), tree.onToggle, tree.onOpen), { fallback: legacy });
|
|
7804
8137
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7805
8138
|
ref: bodyRef,
|
|
7806
8139
|
className: css$1.body,
|
|
7807
8140
|
onScroll: (event) => {
|
|
7808
8141
|
scrollTopRef.current = event.currentTarget.scrollTop;
|
|
7809
8142
|
},
|
|
7810
|
-
children:
|
|
7811
|
-
className: css$1.level,
|
|
7812
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Level, {
|
|
7813
|
-
path: state.root,
|
|
7814
|
-
tree
|
|
7815
|
-
})
|
|
7816
|
-
})
|
|
8143
|
+
children: content
|
|
7817
8144
|
});
|
|
7818
8145
|
}
|
|
7819
8146
|
//#endregion
|
|
@@ -7986,7 +8313,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7986
8313
|
};
|
|
7987
8314
|
}
|
|
7988
8315
|
//#endregion
|
|
7989
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-host-open-in-app@0.2.2-
|
|
8316
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-host-open-in-app@0.2.2-rc.1_@deepseek-ai+cordis@4.1.0_@deepseek-ai+dsh_33f3d65190f3ff17e4e9438df89ed28d/node_modules/@deepseek-ai/dsh-host-open-in-app/lib/types/shared.js
|
|
7990
8317
|
var shared_exports = /* @__PURE__ */ __exportAll({
|
|
7991
8318
|
OPEN_IN_APP_APPS_PATH: () => OPEN_IN_APP_APPS_PATH,
|
|
7992
8319
|
OPEN_IN_APP_APPS_ROUTE: () => OPEN_IN_APP_APPS_ROUTE,
|
|
@@ -9668,7 +9995,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9668
9995
|
sectionRef.current = wrapper?.closest("[data-dockkit-content]") ?? null;
|
|
9669
9996
|
const content = sectionRef.current?.dataset.dockkitContent;
|
|
9670
9997
|
setTabId(content !== void 0 && content !== "" ? content : fallbackTabId.current ??= `mrfw-${Math.random().toString(36).slice(2)}`);
|
|
9671
|
-
setPane(wrapper?.closest("[data-files-root]") ?? null);
|
|
9998
|
+
setPane(wrapper?.closest("[data-files-page]") ?? wrapper?.closest("[data-files-root]") ?? null);
|
|
9672
9999
|
}, []);
|
|
9673
10000
|
const selected = (filesTree?.useTreeSelection ?? noTreeSelection)((selection) => tabId === void 0 ? void 0 : selection[tabId]) ?? "primary";
|
|
9674
10001
|
const selectRoot = filesTree?.selectRoot;
|
|
@@ -9867,7 +10194,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9867
10194
|
start: filesTree.face.start,
|
|
9868
10195
|
toggle: filesTree.face.toggle,
|
|
9869
10196
|
onOpen: filesTree.openFile,
|
|
9870
|
-
t: filesTree.t
|
|
10197
|
+
t: filesTree.t,
|
|
10198
|
+
nativeTree: pane.hasAttribute("data-files-page") ? props.nativeTree : void 0
|
|
9871
10199
|
}), pane) : null,
|
|
9872
10200
|
dialogOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkspaceFoldersDialog, {
|
|
9873
10201
|
panel: props.panel,
|
|
@@ -9990,7 +10318,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9990
10318
|
subscribeSession,
|
|
9991
10319
|
t,
|
|
9992
10320
|
openInApp: openInApp?.adapter,
|
|
9993
|
-
filesTree
|
|
10321
|
+
filesTree,
|
|
10322
|
+
nativeTree: nativeTreeRenderer(props.renderFactorySlot)
|
|
9994
10323
|
});
|
|
9995
10324
|
}));
|
|
9996
10325
|
}
|