@dsh-electron/dsh-plugin-multi-root-workspace 0.1.12 → 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 +29 -1
- package/CHANGELOG.md +29 -1
- package/README.en.md +9 -8
- package/README.md +9 -8
- package/cordis.patch.yml +4 -0
- 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 +492 -87
- package/lib/client.js.map +1 -1
- package/lib/{command-CmLekG1M.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-4zdwV7u4.js → protocol-CnR1KTXy.js} +62 -9
- package/lib/{registry-YTUOjmVu.js → registry-DR_sMuvS.js} +425 -125
- package/lib/{registry-lease-win32-DVTq9d4D.js → registry-lease-win32-DDO-c7ig.js} +2 -1
- package/lib/registry.js +2 -2
- package/lib/scope.js +36 -2
- package/lib/types/authority/protocol.d.ts +1 -1
- package/lib/types/authority/recovery.d.ts +58 -0
- package/lib/types/client/RootSwitcher.d.ts +8 -3
- 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/adapter.d.ts +63 -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/lib/types/registry.d.ts +98 -0
- package/lib/types/scope.d.ts +18 -0
- 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
|
@@ -40,8 +40,8 @@ window.__ModuleLoader__.load({
|
|
|
40
40
|
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
41
41
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
42
42
|
let react_dom = require("react-dom");
|
|
43
|
-
require("@deepseek-ai/cordis");
|
|
44
43
|
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
44
|
+
require("@deepseek-ai/cordis");
|
|
45
45
|
//#region src/compat/client-session.ts
|
|
46
46
|
/**
|
|
47
47
|
* The session the composed client is showing, when it can name one.
|
|
@@ -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
|
|
@@ -7902,12 +8229,59 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7902
8229
|
const store = createFilesStore();
|
|
7903
8230
|
const remote = lazyFilesRemote(ctx);
|
|
7904
8231
|
const face = filesFace(createList(remote), createWatch(remote));
|
|
7905
|
-
const inject = (sessionId, actions) =>
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
8232
|
+
const inject = (sessionId, actions) => {
|
|
8233
|
+
const selection = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({});
|
|
8234
|
+
const takeovers = /* @__PURE__ */ new Map();
|
|
8235
|
+
const endTakeover = (tabId) => {
|
|
8236
|
+
const held = takeovers.get(tabId);
|
|
8237
|
+
held?.observer?.disconnect();
|
|
8238
|
+
held?.controller.abort();
|
|
8239
|
+
takeovers.delete(tabId);
|
|
8240
|
+
};
|
|
8241
|
+
return {
|
|
8242
|
+
face: face(sessionId, actions),
|
|
8243
|
+
openFile: (address) => {
|
|
8244
|
+
ctx.get("sidebarRight")?.openResourceIn?.(sessionId, address);
|
|
8245
|
+
},
|
|
8246
|
+
hooks: { treeSelection: selection },
|
|
8247
|
+
selectRoot: (tabId, root) => {
|
|
8248
|
+
const next = { ...selection.getSnapshot() };
|
|
8249
|
+
if (root === "primary") delete next[tabId];
|
|
8250
|
+
else next[tabId] = root;
|
|
8251
|
+
selection.set(next);
|
|
8252
|
+
},
|
|
8253
|
+
takeover: {
|
|
8254
|
+
signal: (tabId, root, section) => {
|
|
8255
|
+
let held = takeovers.get(tabId);
|
|
8256
|
+
if (held === void 0 || held.root !== root || held.controller.signal.aborted) {
|
|
8257
|
+
held?.observer?.disconnect();
|
|
8258
|
+
held?.controller.abort();
|
|
8259
|
+
held = {
|
|
8260
|
+
controller: new AbortController(),
|
|
8261
|
+
root,
|
|
8262
|
+
section: void 0,
|
|
8263
|
+
observer: void 0
|
|
8264
|
+
};
|
|
8265
|
+
takeovers.set(tabId, held);
|
|
8266
|
+
}
|
|
8267
|
+
if (section !== void 0 && held.section !== section) {
|
|
8268
|
+
held.section = section;
|
|
8269
|
+
held.observer?.disconnect();
|
|
8270
|
+
held.observer = new MutationObserver(() => {
|
|
8271
|
+
if (!section.isConnected) endTakeover(tabId);
|
|
8272
|
+
});
|
|
8273
|
+
held.observer.observe(document, {
|
|
8274
|
+
childList: true,
|
|
8275
|
+
subtree: true
|
|
8276
|
+
});
|
|
8277
|
+
}
|
|
8278
|
+
if (held.section !== void 0 && !held.section.isConnected) endTakeover(tabId);
|
|
8279
|
+
return held.controller.signal;
|
|
8280
|
+
},
|
|
8281
|
+
end: endTakeover
|
|
8282
|
+
}
|
|
8283
|
+
};
|
|
8284
|
+
};
|
|
7911
8285
|
return {
|
|
7912
8286
|
store,
|
|
7913
8287
|
inject
|
|
@@ -7924,19 +8298,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7924
8298
|
*/
|
|
7925
8299
|
function createFilesTreeSurface(props, t) {
|
|
7926
8300
|
if (!filesTreeSurfaceSupported()) return void 0;
|
|
7927
|
-
const { sessionId, useStore, actions, face, openFile } = props;
|
|
7928
|
-
if (face === void 0 || openFile === void 0 || useStore === void 0 || actions === void 0) return void 0;
|
|
8301
|
+
const { sessionId, useStore, actions, face, openFile, useTreeSelection, selectRoot, takeover } = props;
|
|
8302
|
+
if (face === void 0 || openFile === void 0 || useStore === void 0 || actions === void 0 || useTreeSelection === void 0 || selectRoot === void 0 || takeover === void 0) return void 0;
|
|
7929
8303
|
return {
|
|
7930
8304
|
sessionId,
|
|
7931
8305
|
useStore,
|
|
7932
8306
|
actions,
|
|
7933
8307
|
face,
|
|
7934
8308
|
openFile,
|
|
8309
|
+
useTreeSelection,
|
|
8310
|
+
selectRoot,
|
|
8311
|
+
takeover,
|
|
7935
8312
|
t
|
|
7936
8313
|
};
|
|
7937
8314
|
}
|
|
7938
8315
|
//#endregion
|
|
7939
|
-
//#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
|
|
7940
8317
|
var shared_exports = /* @__PURE__ */ __exportAll({
|
|
7941
8318
|
OPEN_IN_APP_APPS_PATH: () => OPEN_IN_APP_APPS_PATH,
|
|
7942
8319
|
OPEN_IN_APP_APPS_ROUTE: () => OPEN_IN_APP_APPS_ROUTE,
|
|
@@ -9574,9 +9951,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9574
9951
|
* the same element's `closest('[data-dockkit-content]')` — the dockkit
|
|
9575
9952
|
* tabHost section — with a generated fallback where the hook is absent.
|
|
9576
9953
|
*
|
|
9577
|
-
* The selected root
|
|
9578
|
-
*
|
|
9579
|
-
*
|
|
9954
|
+
* The selected root lives in the inject product's session-scoped snapshot,
|
|
9955
|
+
* keyed by that dockkit tab id — component state could not survive the
|
|
9956
|
+
* remount every file open causes (the opened tab takes the pane, the Files
|
|
9957
|
+
* body unmounts with the whole occupant subtree). One selection per tab;
|
|
9958
|
+
* session switches mint a fresh inject product, so no selection crosses
|
|
9959
|
+
* sessions, and a registry eviction reconciles it back to primary.
|
|
9580
9960
|
*
|
|
9581
9961
|
* @module @dsh-electron/dsh-plugin-multi-root-workspace/client/RootSwitcher
|
|
9582
9962
|
*/
|
|
@@ -9587,17 +9967,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9587
9967
|
* path stays readable and hoverable, only the dir/file typography differs.
|
|
9588
9968
|
*/
|
|
9589
9969
|
const PathLabel = maybeComponent(["PathLabel"]);
|
|
9970
|
+
/** Selector hook for a composition without the fork: nothing was ever selectable. */
|
|
9971
|
+
const noTreeSelection = () => void 0;
|
|
9590
9972
|
/** The Files-header switcher: root menu, dialog entry, and the portal tree. */
|
|
9591
9973
|
function RootSwitcher(props) {
|
|
9592
9974
|
const { panel, t, primaryPath, filesTree } = props;
|
|
9593
9975
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
9594
9976
|
const [dialogOpen, setDialogOpen] = (0, react.useState)(false);
|
|
9595
9977
|
const [view, setView] = (0, react.useState)(void 0);
|
|
9596
|
-
const [selected, setSelected] = (0, react.useState)("primary");
|
|
9597
9978
|
const [takeover, setTakeover] = (0, react.useState)(null);
|
|
9598
9979
|
const wrapperRef = (0, react.useRef)(null);
|
|
9599
9980
|
const fallbackTabId = (0, react.useRef)(void 0);
|
|
9981
|
+
const sectionRef = (0, react.useRef)(null);
|
|
9600
9982
|
const [pane, setPane] = (0, react.useState)(null);
|
|
9983
|
+
const [tabId, setTabId] = (0, react.useState)(void 0);
|
|
9601
9984
|
const mounted = (0, react.useRef)(true);
|
|
9602
9985
|
const requestEpoch = (0, react.useRef)(0);
|
|
9603
9986
|
(0, react.useEffect)(() => {
|
|
@@ -9608,8 +9991,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9608
9991
|
};
|
|
9609
9992
|
}, []);
|
|
9610
9993
|
(0, react.useEffect)(() => {
|
|
9611
|
-
|
|
9994
|
+
const wrapper = wrapperRef.current;
|
|
9995
|
+
sectionRef.current = wrapper?.closest("[data-dockkit-content]") ?? null;
|
|
9996
|
+
const content = sectionRef.current?.dataset.dockkitContent;
|
|
9997
|
+
setTabId(content !== void 0 && content !== "" ? content : fallbackTabId.current ??= `mrfw-${Math.random().toString(36).slice(2)}`);
|
|
9998
|
+
setPane(wrapper?.closest("[data-files-page]") ?? wrapper?.closest("[data-files-root]") ?? null);
|
|
9612
9999
|
}, []);
|
|
10000
|
+
const selected = (filesTree?.useTreeSelection ?? noTreeSelection)((selection) => tabId === void 0 ? void 0 : selection[tabId]) ?? "primary";
|
|
10001
|
+
const selectRoot = filesTree?.selectRoot;
|
|
10002
|
+
const setSelected = (0, react.useCallback)((next) => {
|
|
10003
|
+
if (selectRoot === void 0 || tabId === void 0) return;
|
|
10004
|
+
selectRoot(tabId, next);
|
|
10005
|
+
}, [selectRoot, tabId]);
|
|
9613
10006
|
const refresh = (0, react.useCallback)(async () => {
|
|
9614
10007
|
if (panel === void 0) {
|
|
9615
10008
|
setView(void 0);
|
|
@@ -9647,39 +10040,48 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9647
10040
|
}, [
|
|
9648
10041
|
props.subscribeSession,
|
|
9649
10042
|
props.sessionId,
|
|
9650
|
-
refresh
|
|
10043
|
+
refresh,
|
|
10044
|
+
setSelected
|
|
9651
10045
|
]);
|
|
9652
10046
|
(0, react.useEffect)(() => {
|
|
9653
|
-
if (selected === "primary") return;
|
|
9654
|
-
const current = view
|
|
10047
|
+
if (selected === "primary" || view === void 0) return;
|
|
10048
|
+
const current = view.roots.find((root) => root.id === selected.id);
|
|
9655
10049
|
if (current === void 0 || current.state !== "available") {
|
|
9656
10050
|
setSelected("primary");
|
|
9657
10051
|
return;
|
|
9658
10052
|
}
|
|
9659
10053
|
if (current !== selected) setSelected(current);
|
|
9660
|
-
}, [
|
|
10054
|
+
}, [
|
|
10055
|
+
view,
|
|
10056
|
+
selected,
|
|
10057
|
+
setSelected
|
|
10058
|
+
]);
|
|
9661
10059
|
const roots = (0, react.useMemo)(() => view?.roots ?? [], [view]);
|
|
9662
10060
|
const primaryLabel = view?.primaryName ?? basename(view?.primaryRoot ?? primaryPath);
|
|
9663
10061
|
const triggerLabel = selected === "primary" ? primaryLabel : displayNameOf(selected);
|
|
9664
10062
|
const triggerPath = selected === "primary" ? view?.primaryRoot ?? primaryPath : selected.path;
|
|
9665
10063
|
const treeVisible = selected !== "primary" && panel !== void 0 && pane !== null && filesTree !== void 0;
|
|
9666
10064
|
const selectedPath = selected === "primary" ? void 0 : selected.path;
|
|
10065
|
+
const takeoverCtl = filesTree?.takeover;
|
|
9667
10066
|
(0, react.useEffect)(() => {
|
|
9668
|
-
if (!treeVisible || selectedPath === void 0) {
|
|
10067
|
+
if (!treeVisible || selectedPath === void 0 || tabId === void 0 || takeoverCtl === void 0) {
|
|
9669
10068
|
setTakeover(null);
|
|
9670
10069
|
return;
|
|
9671
10070
|
}
|
|
9672
|
-
const controller = new AbortController();
|
|
9673
|
-
const tabId = (wrapperRef.current?.closest("[data-dockkit-content]")?.dataset.dockkitContent ?? "") || (fallbackTabId.current ??= `mrfw-${Math.random().toString(36).slice(2)}`);
|
|
9674
10071
|
setTakeover({
|
|
9675
|
-
signal:
|
|
10072
|
+
signal: takeoverCtl.signal(tabId, selectedPath, sectionRef.current ?? void 0),
|
|
9676
10073
|
tabId,
|
|
9677
10074
|
root: selectedPath
|
|
9678
10075
|
});
|
|
9679
10076
|
return () => {
|
|
9680
|
-
|
|
10077
|
+
if (mounted.current || sectionRef.current === null) takeoverCtl.end(tabId);
|
|
9681
10078
|
};
|
|
9682
|
-
}, [
|
|
10079
|
+
}, [
|
|
10080
|
+
treeVisible,
|
|
10081
|
+
selectedPath,
|
|
10082
|
+
tabId,
|
|
10083
|
+
takeoverCtl
|
|
10084
|
+
]);
|
|
9683
10085
|
const items = (0, react.useMemo)(() => [{
|
|
9684
10086
|
id: "primary",
|
|
9685
10087
|
label: `${primaryLabel} · ${t("panel.primary")}`,
|
|
@@ -9792,7 +10194,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9792
10194
|
start: filesTree.face.start,
|
|
9793
10195
|
toggle: filesTree.face.toggle,
|
|
9794
10196
|
onOpen: filesTree.openFile,
|
|
9795
|
-
t: filesTree.t
|
|
10197
|
+
t: filesTree.t,
|
|
10198
|
+
nativeTree: pane.hasAttribute("data-files-page") ? props.nativeTree : void 0
|
|
9796
10199
|
}), pane) : null,
|
|
9797
10200
|
dialogOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkspaceFoldersDialog, {
|
|
9798
10201
|
panel: props.panel,
|
|
@@ -9897,7 +10300,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9897
10300
|
inject: filesTreeSeats.inject
|
|
9898
10301
|
}, function FilesActionsOccupant(props) {
|
|
9899
10302
|
const absolutePath = props?.absolutePath;
|
|
9900
|
-
const
|
|
10303
|
+
const composedSessionId = props?.sessionId;
|
|
10304
|
+
const paneSessionId = (0, react.useCallback)(() => composedSessionId ?? sessionId(), [composedSessionId]);
|
|
9901
10305
|
const filesTree = createFilesTreeSurface(props, filesTreeT);
|
|
9902
10306
|
return absolutePath === void 0 ? (0, react.createElement)(WorkspaceFoldersAction, {
|
|
9903
10307
|
panel,
|
|
@@ -9914,7 +10318,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9914
10318
|
subscribeSession,
|
|
9915
10319
|
t,
|
|
9916
10320
|
openInApp: openInApp?.adapter,
|
|
9917
|
-
filesTree
|
|
10321
|
+
filesTree,
|
|
10322
|
+
nativeTree: nativeTreeRenderer(props.renderFactorySlot)
|
|
9918
10323
|
});
|
|
9919
10324
|
}));
|
|
9920
10325
|
}
|