@dsh-electron/dsh-plugin-multi-root-workspace 0.1.13 → 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 +36 -1
- package/CHANGELOG.md +36 -1
- package/README.en.md +27 -10
- package/README.md +27 -10
- package/cordis.patch.yml +5 -1
- 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/{llm-message-fYORacvh.js → agent-instructions-BXuKhOzr.js} +1 -84
- package/lib/auto-review.js +2 -2
- package/lib/client.js +584 -73
- package/lib/client.js.map +1 -1
- package/lib/{command-B9855H7y.js → command-y5tfcAeC.js} +45 -12
- 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-Bg2HFVMX.js → dsh-version-DCwF7REk.js} +5 -265
- package/lib/{fs-CfzJq2wd.js → fs-Uws0ZpmV.js} +38 -0
- package/lib/fs.js +1 -1
- package/lib/index.js +11 -9
- 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-2waCRkPI.js → native-win32-C5oMtt7f.js} +2 -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-CJOvAvOS.js → protocol-CwDnFEyK.js} +54 -8
- package/lib/{registry-Bv431TfO.js → registry-DyDNDSJZ.js} +235 -79
- package/lib/{registry-lease-win32-DVTq9d4D.js → registry-lease-win32-r4puac9m.js} +2 -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/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 +40 -0
- package/lib/types/client/open-in-app/locales.d.ts +1 -1
- package/lib/types/client/ops-settings.d.ts +6 -0
- package/lib/types/client/skills-settings.d.ts +13 -0
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/command.d.ts +3 -3
- 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/instruction-activity.d.ts +32 -1
- package/lib/types/compat/koffi.d.ts +2 -0
- 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/fs.d.ts +3 -1
- 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/locale/en.json +7 -0
- package/locale/zh.json +7 -0
- package/package.json +93 -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,22 @@ 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": "设置保存失败,请重试。",
|
|
5596
|
+
"ops.compatibilityEnable": "OPS 兼容模式",
|
|
5597
|
+
"ops.experimental": "实验性",
|
|
5598
|
+
"ops.compatibilityHint": "仅限 DSH 0.2.*。启用 OPS 写保护、实时活动与 Review 增强。受限模式可能拒绝附加根操作(包括读取),后台缓存可能残留;关闭时显式只读附加根可能被 OPS 写入。",
|
|
5599
|
+
"ops.settingsFailed": "设置保存失败,请重试。",
|
|
5600
|
+
"ops.confirmTitle": "开启 OPS 实验性兼容?",
|
|
5601
|
+
"ops.confirmDescription": "这仍是有限的实验性适配。开启后,附加根的合法读写及部分 PTC 操作可能被拒绝;Windows 存在只读边界时,OPS 读取和执行也可能被拒绝。Linux 批处理或结果读取、后台任务及清理可能不可用,并留下缓存。活动记录尚不持久化,恢复会话或审查动态操作时,Review 可能因证据不足而失败。目前尚未实现 OPS 全功能兼容,请仅在能接受这些限制时开启。",
|
|
5602
|
+
"ops.confirmAcknowledge": "我已了解上述限制,仍要开启实验性兼容",
|
|
5603
|
+
"ops.confirmCancel": "暂不开启",
|
|
5604
|
+
"ops.confirmClose": "关闭并保持未开启",
|
|
5605
|
+
"ops.confirmEnable": "确认开启",
|
|
5548
5606
|
"skills.userOnly": "仅用户调用",
|
|
5549
5607
|
"panel.skills": "目录技能",
|
|
5550
5608
|
"panel.skillsEnabled": "此目录技能已启用,点击停用",
|
|
@@ -5589,6 +5647,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5589
5647
|
"panel.copied": "已复制",
|
|
5590
5648
|
"panel.reveal": "在文件管理器中显示",
|
|
5591
5649
|
"panel.reRegister": "重新登记(保留原访问级别)",
|
|
5650
|
+
"panel.redirectedHint": "目标已改变:请移除该登记后再显式添加新目录。",
|
|
5592
5651
|
"panel.moveUp": "上移",
|
|
5593
5652
|
"panel.moveDown": "下移",
|
|
5594
5653
|
"access.inherit": "跟随会话",
|
|
@@ -5625,6 +5684,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5625
5684
|
"error.copy-failed": "无法写入剪贴板,请检查浏览器的剪贴板权限。",
|
|
5626
5685
|
"error.session-not-found": "找不到该会话;请先打开一个工作区会话。",
|
|
5627
5686
|
"error.unsupported-path": "该路径是网络或设备路径,Windows ACL 隔离无法覆盖它。",
|
|
5687
|
+
"error.protected-path": "该目录与 DSH 主目录或根登记存储目录重叠,不能登记。",
|
|
5688
|
+
"error.protected-boundary-unknown": "暂时无法确定 DSH 主目录等受保护目录的位置;恢复之前不能新增登记。",
|
|
5689
|
+
"error.revive-target-changed": "该登记现在指向另一个目录;请先移除它,再显式添加新目录。",
|
|
5628
5690
|
"error.fallback": "操作失败。"
|
|
5629
5691
|
};
|
|
5630
5692
|
/** English copy, pinned to the Chinese key set. */
|
|
@@ -5632,6 +5694,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5632
5694
|
"skills.globalEnable": "Enable additional-root Skills",
|
|
5633
5695
|
"skills.globalHint": "Controls discovery and new invocations for all additional folders, preserving each folder’s choice.",
|
|
5634
5696
|
"skills.settingsFailed": "Could not save settings. Please try again.",
|
|
5697
|
+
"autoReview.title": "Multi-root Auto Review",
|
|
5698
|
+
"autoReview.experimental": "Experimental",
|
|
5699
|
+
"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.",
|
|
5700
|
+
"autoReview.loadFailed": "Could not read plugin state.",
|
|
5701
|
+
"autoReview.restartRequired": "The change takes effect after restart.",
|
|
5702
|
+
"autoReview.settingsFailed": "Could not save settings. Please try again.",
|
|
5703
|
+
"ops.compatibilityEnable": "OPS compatibility mode",
|
|
5704
|
+
"ops.experimental": "Experimental",
|
|
5705
|
+
"ops.compatibilityHint": "Requires DSH 0.2.*. Enables OPS write protection, live activity, and Review enhancements. Restricted modes may reject additional-root operations, including reads, and background caches may remain. When off, OPS may write to an explicitly read-only additional root.",
|
|
5706
|
+
"ops.settingsFailed": "Could not save settings. Please try again.",
|
|
5707
|
+
"ops.confirmTitle": "Enable experimental OPS compatibility?",
|
|
5708
|
+
"ops.confirmDescription": "This is a limited experimental adaptation. Valid additional-root reads/writes and some PTC calls may be rejected; Windows may also block OPS reads and execution when read-only boundaries apply. Linux batch/result operations, background tasks, and cleanup may fail or leave caches behind. Activity is not persisted: after resume, or when reviewing dynamic operations, Review may fail for lack of evidence. Full OPS compatibility is not available. Enable only if you accept these limitations.",
|
|
5709
|
+
"ops.confirmAcknowledge": "I understand these limitations and want to enable experimental compatibility",
|
|
5710
|
+
"ops.confirmCancel": "Keep disabled",
|
|
5711
|
+
"ops.confirmClose": "Close and keep disabled",
|
|
5712
|
+
"ops.confirmEnable": "Confirm and enable",
|
|
5635
5713
|
"skills.userOnly": "User invocation only",
|
|
5636
5714
|
"panel.skills": "Folder skills",
|
|
5637
5715
|
"panel.skillsEnabled": "Skills enabled for this folder. Click to disable.",
|
|
@@ -5676,6 +5754,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5676
5754
|
"panel.copied": "Copied",
|
|
5677
5755
|
"panel.reveal": "Reveal in file manager",
|
|
5678
5756
|
"panel.reRegister": "Re-register (keeps its access level)",
|
|
5757
|
+
"panel.redirectedHint": "The target changed: remove this registration, then add the new folder explicitly.",
|
|
5679
5758
|
"panel.moveUp": "Move up",
|
|
5680
5759
|
"panel.moveDown": "Move down",
|
|
5681
5760
|
"access.inherit": "Inherit",
|
|
@@ -5712,6 +5791,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5712
5791
|
"error.copy-failed": "Could not write to the clipboard; check the browser's clipboard permission.",
|
|
5713
5792
|
"error.session-not-found": "That session is not active; open a workspace session first.",
|
|
5714
5793
|
"error.unsupported-path": "That is a network or device path, which Windows ACL confinement cannot cover.",
|
|
5794
|
+
"error.protected-path": "That directory overlaps the DSH home or the registry storage directories; it cannot be registered.",
|
|
5795
|
+
"error.protected-boundary-unknown": "The protected DSH directories cannot be resolved right now; no folder can be registered until they can.",
|
|
5796
|
+
"error.revive-target-changed": "That registration now resolves to a different directory; remove it, then add the new folder explicitly.",
|
|
5715
5797
|
"error.fallback": "The operation failed."
|
|
5716
5798
|
};
|
|
5717
5799
|
//#endregion
|
|
@@ -5928,6 +6010,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5928
6010
|
display: none;
|
|
5929
6011
|
}
|
|
5930
6012
|
|
|
6013
|
+
/* Newer Files pages place the navigator beside the header instead of
|
|
6014
|
+
wrapping both in data-files-root. Target the page without hiding the
|
|
6015
|
+
portaled replacement or any of its rows. */
|
|
6016
|
+
[data-files-page]:has(.mrfw-fileLauncher) [data-files-path]:not([data-files-entry]) { order: -2; }
|
|
6017
|
+
[data-files-page]:has(.mrfw-rootSwitcher) [data-files-path]:not([data-files-entry]) { display: none; }
|
|
6018
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-files-content],
|
|
6019
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-files-reload] { display: none; }
|
|
6020
|
+
[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)),
|
|
6021
|
+
[data-files-page]:has(.mrfw-rootSwitcher[data-root-kind="additional"]) [data-open-target="directory"]:not(.mrfw-openSplit) { display: none; }
|
|
6022
|
+
|
|
5931
6023
|
/* While the switcher names an additional root, the native open-in-app split
|
|
5932
6024
|
button hides too: its slot props carry the pane's primary root, so it
|
|
5933
6025
|
would always open the primary root no matter what the switcher selected.
|
|
@@ -6360,6 +6452,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6360
6452
|
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
6361
6453
|
}
|
|
6362
6454
|
.mrfw-skillsSettingsText { min-width: 0; }
|
|
6455
|
+
.mrfw-settingsTitleRow {
|
|
6456
|
+
display: flex;
|
|
6457
|
+
align-items: center;
|
|
6458
|
+
gap: 8px;
|
|
6459
|
+
}
|
|
6363
6460
|
.mrfw-skillsSettingsTitle { font-size: 14px; line-height: 20px; }
|
|
6364
6461
|
.mrfw-skillsSettingsDescription {
|
|
6365
6462
|
margin-top: 4px;
|
|
@@ -6613,10 +6710,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6613
6710
|
`;
|
|
6614
6711
|
//#endregion
|
|
6615
6712
|
//#region src/compat/skills-client.ts
|
|
6616
|
-
function
|
|
6713
|
+
function bindSettingsForm(ctx, entryId) {
|
|
6617
6714
|
const modern = ctx.get("configForms");
|
|
6618
|
-
if (modern !== void 0) return modern.get(
|
|
6619
|
-
return ctx.get("settingsScope")?.bind({ namespace:
|
|
6715
|
+
if (modern !== void 0) return modern.get(entryId);
|
|
6716
|
+
return ctx.get("settingsScope")?.bind({ namespace: entryId });
|
|
6717
|
+
}
|
|
6718
|
+
function bindSkillsForm(ctx) {
|
|
6719
|
+
return bindSettingsForm(ctx, "multi-root-skills");
|
|
6620
6720
|
}
|
|
6621
6721
|
function clientInject(ctx, services, callback) {
|
|
6622
6722
|
if (typeof ctx.inject === "function") ctx.inject(services, callback);
|
|
@@ -6842,102 +6942,503 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6842
6942
|
});
|
|
6843
6943
|
}
|
|
6844
6944
|
//#endregion
|
|
6945
|
+
//#region src/compat/auto-review-client.ts
|
|
6946
|
+
/** The module specifier `cordis.patch.yml` gives the optional row. */
|
|
6947
|
+
const AUTO_REVIEW_MODULE = "@dsh-electron/dsh-plugin-multi-root-workspace/auto-review";
|
|
6948
|
+
var AutoReviewSettingsForm = class {
|
|
6949
|
+
snapshot = { status: "unavailable" };
|
|
6950
|
+
listeners = /* @__PURE__ */ new Set();
|
|
6951
|
+
manager;
|
|
6952
|
+
stopEvents;
|
|
6953
|
+
epoch = 0;
|
|
6954
|
+
refreshSeq = 0;
|
|
6955
|
+
getSnapshot() {
|
|
6956
|
+
return this.snapshot;
|
|
6957
|
+
}
|
|
6958
|
+
subscribe(listener) {
|
|
6959
|
+
this.listeners.add(listener);
|
|
6960
|
+
return () => {
|
|
6961
|
+
this.listeners.delete(listener);
|
|
6962
|
+
};
|
|
6963
|
+
}
|
|
6964
|
+
publish(next) {
|
|
6965
|
+
this.snapshot = next;
|
|
6966
|
+
for (const listener of [...this.listeners]) listener();
|
|
6967
|
+
}
|
|
6968
|
+
attach(manager, remote) {
|
|
6969
|
+
this.detach();
|
|
6970
|
+
this.manager = manager;
|
|
6971
|
+
this.epoch++;
|
|
6972
|
+
this.publish({ status: "loading" });
|
|
6973
|
+
if (remote !== void 0) try {
|
|
6974
|
+
this.stopEvents = remote.$on("plugin-manager/changed", () => {
|
|
6975
|
+
this.refresh();
|
|
6976
|
+
});
|
|
6977
|
+
} catch {
|
|
6978
|
+
this.stopEvents = void 0;
|
|
6979
|
+
}
|
|
6980
|
+
this.refresh();
|
|
6981
|
+
}
|
|
6982
|
+
detach() {
|
|
6983
|
+
this.stopEvents?.();
|
|
6984
|
+
this.stopEvents = void 0;
|
|
6985
|
+
this.manager = void 0;
|
|
6986
|
+
this.epoch++;
|
|
6987
|
+
this.publish({ status: "unavailable" });
|
|
6988
|
+
}
|
|
6989
|
+
async refresh() {
|
|
6990
|
+
const manager = this.manager;
|
|
6991
|
+
const epoch = this.epoch;
|
|
6992
|
+
const seq = ++this.refreshSeq;
|
|
6993
|
+
if (manager === void 0) return;
|
|
6994
|
+
const result = await manager.listPlugins();
|
|
6995
|
+
if (manager !== this.manager || epoch !== this.epoch || seq !== this.refreshSeq) return;
|
|
6996
|
+
if (!result.ok) {
|
|
6997
|
+
this.publish({ status: "error" });
|
|
6998
|
+
return;
|
|
6999
|
+
}
|
|
7000
|
+
const entry = result.value.find((item) => item.moduleName === AUTO_REVIEW_MODULE);
|
|
7001
|
+
this.publish(entry === void 0 ? { status: "ready" } : {
|
|
7002
|
+
status: "ready",
|
|
7003
|
+
row: {
|
|
7004
|
+
entryId: entry.entryId,
|
|
7005
|
+
enabled: entry.enabled,
|
|
7006
|
+
writable: entry.readOnlyReason === void 0,
|
|
7007
|
+
...entry.diagnostic === void 0 ? {} : { diagnostic: entry.diagnostic }
|
|
7008
|
+
}
|
|
7009
|
+
});
|
|
7010
|
+
}
|
|
7011
|
+
async setEnabled(enabled) {
|
|
7012
|
+
const manager = this.manager;
|
|
7013
|
+
const row = this.snapshot.status === "ready" ? this.snapshot.row : void 0;
|
|
7014
|
+
if (manager === void 0 || row === void 0) return "failed";
|
|
7015
|
+
const result = await manager.setPluginEnabled(row.entryId, enabled);
|
|
7016
|
+
await this.refresh();
|
|
7017
|
+
if (!result.ok) return "failed";
|
|
7018
|
+
const application = result.value.application;
|
|
7019
|
+
return application === "applied" || application === "restart-required" ? application : "failed";
|
|
7020
|
+
}
|
|
7021
|
+
};
|
|
7022
|
+
/**
|
|
7023
|
+
* Create the card's Auto Review handle and attach it when the host's
|
|
7024
|
+
* `pluginManager` namespace arrives. The returned form exists immediately with
|
|
7025
|
+
* status `unavailable` and publishes on every attach/detach/read, so callers
|
|
7026
|
+
* only need `subscribe` — no separate availability callback.
|
|
7027
|
+
* @param ctx - the client root context.
|
|
7028
|
+
* @returns the stable form the settings row renders.
|
|
7029
|
+
*/
|
|
7030
|
+
function installAutoReviewSettings(ctx) {
|
|
7031
|
+
const form = new AutoReviewSettingsForm();
|
|
7032
|
+
clientInject(ctx, ["remote.pluginManager"], (scope) => {
|
|
7033
|
+
const manager = scope.get("remote.pluginManager");
|
|
7034
|
+
if (manager === void 0) return;
|
|
7035
|
+
const remote = scope.get("remote");
|
|
7036
|
+
form.attach(manager, remote);
|
|
7037
|
+
return () => {
|
|
7038
|
+
form.detach();
|
|
7039
|
+
};
|
|
7040
|
+
});
|
|
7041
|
+
return form;
|
|
7042
|
+
}
|
|
7043
|
+
//#endregion
|
|
7044
|
+
//#region src/client/auto-review-settings.tsx
|
|
7045
|
+
/**
|
|
7046
|
+
* Full-opacity hold for the card's message toasts — the same window upstream
|
|
7047
|
+
* gives a refusal banner, since these strings name what broke rather than
|
|
7048
|
+
* reporting a one-line limit.
|
|
7049
|
+
*/
|
|
7050
|
+
const TOAST_HOLD_MS = 8e3;
|
|
7051
|
+
/**
|
|
7052
|
+
* The optional Auto Review row of the plugin settings card.
|
|
7053
|
+
*
|
|
7054
|
+
* Its switch is the Loader row's own enablement — the same write the Plugin
|
|
7055
|
+
* Manager's row switch performs — so the card can never disagree with the row
|
|
7056
|
+
* list about whether the companion is on. Feedback is a transient `Toast`
|
|
7057
|
+
* banner, never inline text: state-driven messages (a failed read, an entry
|
|
7058
|
+
* diagnostic) fire on entry and clear when their source resolves, while write
|
|
7059
|
+
* outcomes report once and fade. The row stays hidden entirely on hosts
|
|
7060
|
+
* without the `pluginManager` namespace or when the composition does not list
|
|
7061
|
+
* the optional entry.
|
|
7062
|
+
*/
|
|
7063
|
+
function AutoReviewSettingsCard({ form, t }) {
|
|
7064
|
+
const snapshot = (0, react.useSyncExternalStore)((listener) => form.subscribe(listener), () => form.getSnapshot());
|
|
7065
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
7066
|
+
const mounted = (0, react.useRef)(true);
|
|
7067
|
+
const toastSeq = (0, react.useRef)(0);
|
|
7068
|
+
const [toast, setToast] = (0, react.useState)(null);
|
|
7069
|
+
(0, react.useEffect)(() => {
|
|
7070
|
+
mounted.current = true;
|
|
7071
|
+
return () => {
|
|
7072
|
+
mounted.current = false;
|
|
7073
|
+
};
|
|
7074
|
+
}, []);
|
|
7075
|
+
const showToast = (0, react.useCallback)((kind, text) => {
|
|
7076
|
+
toastSeq.current += 1;
|
|
7077
|
+
setToast({
|
|
7078
|
+
seq: toastSeq.current,
|
|
7079
|
+
kind,
|
|
7080
|
+
text
|
|
7081
|
+
});
|
|
7082
|
+
}, []);
|
|
7083
|
+
const dismissToast = (0, react.useCallback)((kind) => {
|
|
7084
|
+
setToast((current) => current?.kind === kind ? null : current);
|
|
7085
|
+
}, []);
|
|
7086
|
+
const status = snapshot.status;
|
|
7087
|
+
const diagnostic = status === "ready" ? snapshot.row?.diagnostic : void 0;
|
|
7088
|
+
(0, react.useEffect)(() => {
|
|
7089
|
+
if (status === "error") showToast("load", t("autoReview.loadFailed"));
|
|
7090
|
+
else dismissToast("load");
|
|
7091
|
+
}, [
|
|
7092
|
+
status,
|
|
7093
|
+
t,
|
|
7094
|
+
showToast,
|
|
7095
|
+
dismissToast
|
|
7096
|
+
]);
|
|
7097
|
+
(0, react.useEffect)(() => {
|
|
7098
|
+
if (diagnostic !== void 0 && diagnostic !== "") showToast("diagnostic", diagnostic);
|
|
7099
|
+
else dismissToast("diagnostic");
|
|
7100
|
+
}, [
|
|
7101
|
+
diagnostic,
|
|
7102
|
+
showToast,
|
|
7103
|
+
dismissToast
|
|
7104
|
+
]);
|
|
7105
|
+
if (status === "unavailable") return null;
|
|
7106
|
+
const row = status === "ready" ? snapshot.row : void 0;
|
|
7107
|
+
if (status === "ready" && row === void 0) return null;
|
|
7108
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7109
|
+
className: "mrfw-skillsSettings",
|
|
7110
|
+
children: [
|
|
7111
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7112
|
+
className: "mrfw-skillsSettingsText",
|
|
7113
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7114
|
+
className: "mrfw-settingsTitleRow",
|
|
7115
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7116
|
+
className: "mrfw-skillsSettingsTitle",
|
|
7117
|
+
children: t("autoReview.title")
|
|
7118
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
7119
|
+
tone: "info",
|
|
7120
|
+
children: t("autoReview.experimental")
|
|
7121
|
+
})]
|
|
7122
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7123
|
+
className: "mrfw-skillsSettingsDescription",
|
|
7124
|
+
children: t("autoReview.hint")
|
|
7125
|
+
})]
|
|
7126
|
+
}),
|
|
7127
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
7128
|
+
label: t("autoReview.title"),
|
|
7129
|
+
checked: row?.enabled ?? false,
|
|
7130
|
+
disabled: busy || row?.writable !== true,
|
|
7131
|
+
onChange: (enabled) => {
|
|
7132
|
+
setBusy(true);
|
|
7133
|
+
form.setEnabled(enabled).then((result) => {
|
|
7134
|
+
if (!mounted.current) return;
|
|
7135
|
+
if (result === "restart-required") showToast("write", t("autoReview.restartRequired"));
|
|
7136
|
+
else if (result === "failed") showToast("write", t("autoReview.settingsFailed"));
|
|
7137
|
+
}).catch(() => {
|
|
7138
|
+
if (mounted.current) showToast("write", t("autoReview.settingsFailed"));
|
|
7139
|
+
}).finally(() => {
|
|
7140
|
+
if (mounted.current) setBusy(false);
|
|
7141
|
+
});
|
|
7142
|
+
}
|
|
7143
|
+
}),
|
|
7144
|
+
toast === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
7145
|
+
text: toast.text,
|
|
7146
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
|
|
7147
|
+
holdMs: TOAST_HOLD_MS,
|
|
7148
|
+
onDone: () => {
|
|
7149
|
+
setToast(null);
|
|
7150
|
+
}
|
|
7151
|
+
}, toast.seq)
|
|
7152
|
+
]
|
|
7153
|
+
});
|
|
7154
|
+
}
|
|
7155
|
+
//#endregion
|
|
7156
|
+
//#region src/compat/ops-confirmation.ts
|
|
7157
|
+
function opsRiskConfirmation() {
|
|
7158
|
+
return _deepseek_ai_dsh_client_ui_primitives.RiskConfirmation;
|
|
7159
|
+
}
|
|
7160
|
+
//#endregion
|
|
7161
|
+
//#region src/client/ops-settings.tsx
|
|
7162
|
+
function OpsCompatibilitySettingsCard({ form, t }) {
|
|
7163
|
+
const snapshot = (0, react.useSyncExternalStore)((listener) => form.subscribe(listener), () => form.getSnapshot());
|
|
7164
|
+
const [busy, setBusy] = (0, react.useState)(false), [error, setError] = (0, react.useState)();
|
|
7165
|
+
const [confirmation, setConfirmation] = (0, react.useState)();
|
|
7166
|
+
const [acknowledged, setAcknowledged] = (0, react.useState)(false);
|
|
7167
|
+
const saving = (0, react.useRef)(false);
|
|
7168
|
+
const mounted = (0, react.useRef)(true);
|
|
7169
|
+
const RiskConfirmation = opsRiskConfirmation();
|
|
7170
|
+
const canConfirm = confirmation !== void 0 && confirmation.form === form && confirmation.revision === snapshot.revision && snapshot.status === "ready" && snapshot.writable && snapshot.value?.enabled !== true && RiskConfirmation !== void 0;
|
|
7171
|
+
const dismiss = () => {
|
|
7172
|
+
setConfirmation(void 0);
|
|
7173
|
+
setAcknowledged(false);
|
|
7174
|
+
};
|
|
7175
|
+
(0, react.useEffect)(() => {
|
|
7176
|
+
mounted.current = true;
|
|
7177
|
+
return () => {
|
|
7178
|
+
mounted.current = false;
|
|
7179
|
+
};
|
|
7180
|
+
}, []);
|
|
7181
|
+
(0, react.useEffect)(() => {
|
|
7182
|
+
if (confirmation !== void 0 && !canConfirm) {
|
|
7183
|
+
setConfirmation(void 0);
|
|
7184
|
+
setAcknowledged(false);
|
|
7185
|
+
}
|
|
7186
|
+
}, [confirmation, canConfirm]);
|
|
7187
|
+
const save = async (enabled, revision) => {
|
|
7188
|
+
if (saving.current) return;
|
|
7189
|
+
saving.current = true;
|
|
7190
|
+
setBusy(true);
|
|
7191
|
+
setError(void 0);
|
|
7192
|
+
try {
|
|
7193
|
+
const ok = await form.mutate([{
|
|
7194
|
+
op: "set",
|
|
7195
|
+
path: ["enabled"],
|
|
7196
|
+
value: enabled
|
|
7197
|
+
}], revision);
|
|
7198
|
+
if (mounted.current && !ok) setError(t("ops.settingsFailed"));
|
|
7199
|
+
} catch {
|
|
7200
|
+
if (mounted.current) setError(t("ops.settingsFailed"));
|
|
7201
|
+
} finally {
|
|
7202
|
+
saving.current = false;
|
|
7203
|
+
if (mounted.current) setBusy(false);
|
|
7204
|
+
}
|
|
7205
|
+
};
|
|
7206
|
+
if (snapshot.status === "unavailable") return null;
|
|
7207
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7208
|
+
className: "mrfw-skillsSettings",
|
|
7209
|
+
children: [
|
|
7210
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7211
|
+
className: "mrfw-skillsSettingsText",
|
|
7212
|
+
children: [
|
|
7213
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7214
|
+
className: "mrfw-settingsTitleRow",
|
|
7215
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7216
|
+
className: "mrfw-skillsSettingsTitle",
|
|
7217
|
+
children: t("ops.compatibilityEnable")
|
|
7218
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
7219
|
+
tone: "info",
|
|
7220
|
+
children: t("ops.experimental")
|
|
7221
|
+
})]
|
|
7222
|
+
}),
|
|
7223
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7224
|
+
className: "mrfw-skillsSettingsDescription",
|
|
7225
|
+
children: t("ops.compatibilityHint")
|
|
7226
|
+
}),
|
|
7227
|
+
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7228
|
+
role: "alert",
|
|
7229
|
+
children: error
|
|
7230
|
+
}) : null
|
|
7231
|
+
]
|
|
7232
|
+
}),
|
|
7233
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
7234
|
+
label: t("ops.compatibilityEnable"),
|
|
7235
|
+
checked: snapshot.value?.enabled === true,
|
|
7236
|
+
disabled: busy || confirmation !== void 0 || snapshot.status !== "ready" || !snapshot.writable || snapshot.value?.enabled !== true && RiskConfirmation === void 0,
|
|
7237
|
+
onChange: (enabled) => {
|
|
7238
|
+
if (!enabled) {
|
|
7239
|
+
save(false, snapshot.revision);
|
|
7240
|
+
return;
|
|
7241
|
+
}
|
|
7242
|
+
setError(void 0);
|
|
7243
|
+
setAcknowledged(false);
|
|
7244
|
+
setConfirmation({
|
|
7245
|
+
form,
|
|
7246
|
+
revision: snapshot.revision
|
|
7247
|
+
});
|
|
7248
|
+
}
|
|
7249
|
+
}),
|
|
7250
|
+
RiskConfirmation === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RiskConfirmation, {
|
|
7251
|
+
open: canConfirm,
|
|
7252
|
+
title: t("ops.confirmTitle"),
|
|
7253
|
+
description: t("ops.confirmDescription"),
|
|
7254
|
+
acknowledgeLabel: t("ops.confirmAcknowledge"),
|
|
7255
|
+
cancelLabel: t("ops.confirmCancel"),
|
|
7256
|
+
closeLabel: t("ops.confirmClose"),
|
|
7257
|
+
confirmLabel: t("ops.confirmEnable"),
|
|
7258
|
+
acknowledged,
|
|
7259
|
+
disabled: busy || !canConfirm,
|
|
7260
|
+
onAcknowledgedChange: setAcknowledged,
|
|
7261
|
+
onCancel: dismiss,
|
|
7262
|
+
onConfirm: () => {
|
|
7263
|
+
if (!canConfirm || !acknowledged || saving.current) return;
|
|
7264
|
+
const revision = confirmation.revision;
|
|
7265
|
+
dismiss();
|
|
7266
|
+
save(true, revision);
|
|
7267
|
+
}
|
|
7268
|
+
})
|
|
7269
|
+
]
|
|
7270
|
+
});
|
|
7271
|
+
}
|
|
7272
|
+
//#endregion
|
|
6845
7273
|
//#region src/client/skills-settings.tsx
|
|
6846
7274
|
const BUNDLE_KEY = "@dsh-electron/dsh-plugin-multi-root-workspace";
|
|
6847
7275
|
function SkillsSettingsCard({ form, t }) {
|
|
6848
7276
|
const snapshot = (0, react.useSyncExternalStore)((listener) => form.subscribe(listener), () => form.getSnapshot());
|
|
6849
|
-
const [busy, setBusy] = (0, react.useState)(false)
|
|
7277
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
6850
7278
|
const mounted = (0, react.useRef)(true);
|
|
7279
|
+
const toastSeq = (0, react.useRef)(0);
|
|
7280
|
+
const [toast, setToast] = (0, react.useState)(null);
|
|
6851
7281
|
(0, react.useEffect)(() => {
|
|
6852
7282
|
mounted.current = true;
|
|
6853
7283
|
return () => {
|
|
6854
7284
|
mounted.current = false;
|
|
6855
7285
|
};
|
|
6856
7286
|
}, []);
|
|
7287
|
+
const showToast = (0, react.useCallback)((text) => {
|
|
7288
|
+
toastSeq.current += 1;
|
|
7289
|
+
setToast({
|
|
7290
|
+
seq: toastSeq.current,
|
|
7291
|
+
text
|
|
7292
|
+
});
|
|
7293
|
+
}, []);
|
|
6857
7294
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6858
7295
|
className: "mrfw-skillsSettings",
|
|
6859
|
-
children: [
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7296
|
+
children: [
|
|
7297
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7298
|
+
className: "mrfw-skillsSettingsText",
|
|
7299
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6863
7300
|
className: "mrfw-skillsSettingsTitle",
|
|
6864
7301
|
children: t("skills.globalEnable")
|
|
6865
|
-
}),
|
|
6866
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7302
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6867
7303
|
className: "mrfw-skillsSettingsDescription",
|
|
6868
7304
|
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
|
-
|
|
7305
|
+
})]
|
|
7306
|
+
}),
|
|
7307
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
7308
|
+
label: t("skills.globalEnable"),
|
|
7309
|
+
checked: snapshot.value?.enabled ?? true,
|
|
7310
|
+
disabled: busy || snapshot.status !== "ready" || !snapshot.writable,
|
|
7311
|
+
onChange: (enabled) => {
|
|
7312
|
+
setBusy(true);
|
|
7313
|
+
form.mutate([{
|
|
7314
|
+
op: "set",
|
|
7315
|
+
path: ["enabled"],
|
|
7316
|
+
value: enabled
|
|
7317
|
+
}], snapshot.revision).then((ok) => {
|
|
7318
|
+
if (mounted.current && !ok) showToast(t("skills.settingsFailed"));
|
|
7319
|
+
}).catch(() => {
|
|
7320
|
+
if (mounted.current) showToast(t("skills.settingsFailed"));
|
|
7321
|
+
}).finally(() => {
|
|
7322
|
+
if (mounted.current) setBusy(false);
|
|
7323
|
+
});
|
|
7324
|
+
}
|
|
7325
|
+
}),
|
|
7326
|
+
toast === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
7327
|
+
text: toast.text,
|
|
7328
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutlineRegular, {}),
|
|
7329
|
+
holdMs: 8e3,
|
|
7330
|
+
onDone: () => {
|
|
7331
|
+
setToast(null);
|
|
7332
|
+
}
|
|
7333
|
+
}, toast.seq)
|
|
7334
|
+
]
|
|
6895
7335
|
});
|
|
6896
7336
|
}
|
|
7337
|
+
/**
|
|
7338
|
+
* The bundle's one `plugins.bundle.config` cell: every plugin-level switch the
|
|
7339
|
+
* package offers, in display order. Each row owns its own form and write path —
|
|
7340
|
+
* Skills and OPS through their settings namespaces, Auto Review through the Plugin
|
|
7341
|
+
* Manager's Loader-row enablement — so one cell never serializes their state.
|
|
7342
|
+
*/
|
|
7343
|
+
function BundleSettingsCard({ form, autoReviewForm, opsForm, t }) {
|
|
7344
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7345
|
+
form !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkillsSettingsCard, {
|
|
7346
|
+
form,
|
|
7347
|
+
t
|
|
7348
|
+
}) : null,
|
|
7349
|
+
autoReviewForm !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoReviewSettingsCard, {
|
|
7350
|
+
form: autoReviewForm,
|
|
7351
|
+
t
|
|
7352
|
+
}) : null,
|
|
7353
|
+
opsForm !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpsCompatibilitySettingsCard, {
|
|
7354
|
+
form: opsForm,
|
|
7355
|
+
t
|
|
7356
|
+
}) : null
|
|
7357
|
+
] });
|
|
7358
|
+
}
|
|
6897
7359
|
function installSkillsSettingsCard(ctx, t) {
|
|
6898
|
-
let
|
|
7360
|
+
let currentSkills;
|
|
7361
|
+
let currentOps;
|
|
7362
|
+
let currentAutoReview = false;
|
|
6899
7363
|
let stop;
|
|
6900
7364
|
const candidates = /* @__PURE__ */ new Map();
|
|
6901
7365
|
const update = () => {
|
|
6902
7366
|
const chosen = [...candidates.entries()].sort(([a], [b]) => Number(b.get("configForms") !== void 0) - Number(a.get("configForms") !== void 0))[0];
|
|
6903
|
-
|
|
7367
|
+
const skillsForm = chosen?.[1].skills;
|
|
7368
|
+
const opsCandidate = chosen?.[1].ops;
|
|
7369
|
+
const opsForm = opsCandidate?.getSnapshot().status === "unavailable" ? void 0 : opsCandidate;
|
|
7370
|
+
const autoSnapshot = autoForm.getSnapshot();
|
|
7371
|
+
const autoAvailable = autoSnapshot.status === "loading" || autoSnapshot.status === "error" || autoSnapshot.status === "ready" && autoSnapshot.row !== void 0;
|
|
7372
|
+
if (skillsForm === void 0 && opsForm === void 0 && !autoAvailable) {
|
|
7373
|
+
if (currentSkills !== void 0 || currentOps !== void 0 || currentAutoReview) {
|
|
7374
|
+
stop?.();
|
|
7375
|
+
stop = void 0;
|
|
7376
|
+
currentSkills = void 0;
|
|
7377
|
+
currentOps = void 0;
|
|
7378
|
+
currentAutoReview = false;
|
|
7379
|
+
}
|
|
7380
|
+
return;
|
|
7381
|
+
}
|
|
7382
|
+
if (currentSkills === skillsForm && currentOps === opsForm && currentAutoReview === autoAvailable) return;
|
|
7383
|
+
const slots = ctx.slots;
|
|
7384
|
+
if (slots === void 0) return;
|
|
6904
7385
|
stop?.();
|
|
6905
7386
|
stop = void 0;
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
const
|
|
6910
|
-
|
|
7387
|
+
currentSkills = skillsForm;
|
|
7388
|
+
currentOps = opsForm;
|
|
7389
|
+
currentAutoReview = autoAvailable;
|
|
7390
|
+
const disposers = [slots.inject("plugins.bundle.config", () => slots.register({
|
|
7391
|
+
name: "plugins.bundle.config",
|
|
7392
|
+
key: BUNDLE_KEY,
|
|
7393
|
+
inject: () => ({
|
|
7394
|
+
form: skillsForm,
|
|
7395
|
+
autoReviewForm: autoForm,
|
|
7396
|
+
opsForm,
|
|
7397
|
+
t
|
|
7398
|
+
})
|
|
7399
|
+
}, BundleSettingsCard))];
|
|
7400
|
+
if (skillsForm !== void 0) disposers.push(slots.inject("settings.plugin.item", () => slots.register({
|
|
6911
7401
|
name: "settings.plugin.item",
|
|
6912
7402
|
key: "multi-root-skills",
|
|
6913
7403
|
inject: () => ({
|
|
6914
|
-
form,
|
|
7404
|
+
form: skillsForm,
|
|
6915
7405
|
t
|
|
6916
7406
|
})
|
|
6917
|
-
}, SkillsSettingsCard))
|
|
6918
|
-
|
|
6919
|
-
|
|
7407
|
+
}, SkillsSettingsCard)));
|
|
7408
|
+
if (opsForm !== void 0) disposers.push(slots.inject("settings.plugin.item", () => slots.register({
|
|
7409
|
+
name: "settings.plugin.item",
|
|
7410
|
+
key: "multi-root-ops-compatibility",
|
|
6920
7411
|
inject: () => ({
|
|
6921
|
-
form,
|
|
7412
|
+
form: opsForm,
|
|
6922
7413
|
t
|
|
6923
7414
|
})
|
|
6924
|
-
},
|
|
7415
|
+
}, OpsCompatibilitySettingsCard)));
|
|
6925
7416
|
stop = () => {
|
|
6926
7417
|
for (const dispose of disposers) dispose();
|
|
6927
7418
|
};
|
|
6928
7419
|
};
|
|
7420
|
+
const autoForm = installAutoReviewSettings(ctx);
|
|
7421
|
+
const stopAutoWatch = autoForm.subscribe(update);
|
|
7422
|
+
update();
|
|
6929
7423
|
for (const service of ["settingsScope", "configForms"]) clientInject(ctx, [service], (scope) => {
|
|
6930
|
-
const
|
|
6931
|
-
|
|
6932
|
-
|
|
7424
|
+
const skills = bindSkillsForm(scope);
|
|
7425
|
+
const ops = scope.get("configForms")?.get("multi-root-ops-compatibility");
|
|
7426
|
+
if (skills === void 0 && ops === void 0) return;
|
|
7427
|
+
const stopOpsWatch = ops?.subscribe(update);
|
|
7428
|
+
candidates.set(scope, {
|
|
7429
|
+
skills,
|
|
7430
|
+
ops
|
|
7431
|
+
});
|
|
6933
7432
|
update();
|
|
6934
7433
|
return () => {
|
|
7434
|
+
stopOpsWatch?.();
|
|
6935
7435
|
candidates.delete(scope);
|
|
6936
7436
|
update();
|
|
6937
7437
|
};
|
|
6938
7438
|
});
|
|
6939
7439
|
ctx.effect(() => () => {
|
|
6940
7440
|
stop?.();
|
|
7441
|
+
stopAutoWatch();
|
|
6941
7442
|
candidates.clear();
|
|
6942
7443
|
});
|
|
6943
7444
|
}
|
|
@@ -7004,7 +7505,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7004
7505
|
const IconAccessReadOnly = maybeIcon(["PermissionIconReadOnlyRegular", "IconReadOnlyRegular"]);
|
|
7005
7506
|
const IconAccessInherit = maybeIcon(["IconWorkspaceTreeOutline16", "IconWorkspaceTreeOutlineRegular"]);
|
|
7006
7507
|
//#endregion
|
|
7007
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-typert-protocol@0.2.2-
|
|
7508
|
+
//#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
7509
|
/** The one Remote failure class shared by owners, the Gateway, and consumers. */
|
|
7009
7510
|
/**
|
|
7010
7511
|
* One Remote call failure: a real Error carrying its stable code and typed
|
|
@@ -7514,7 +8015,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7514
8015
|
return n;
|
|
7515
8016
|
}
|
|
7516
8017
|
//#endregion
|
|
7517
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.2-
|
|
8018
|
+
//#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
8019
|
/**
|
|
7519
8020
|
* The `dsh-resource://file/…` address grammar: how a file is named across the
|
|
7520
8021
|
* Sidebar and the resource model, built and parsed without touching a
|
|
@@ -7760,7 +8261,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7760
8261
|
* has opened under it — the upstream body's scroll, seed, and render logic
|
|
7761
8262
|
* verbatim, with the root arriving as a prop instead of `useSessions(cwd)`.
|
|
7762
8263
|
*/
|
|
7763
|
-
function FilesTree({ tabId, sessionId, root, signal, useStore, actions, start, toggle, onOpen, t }) {
|
|
8264
|
+
function FilesTree({ tabId, sessionId, root, signal, useStore, actions, start, toggle, onOpen, t, nativeTree }) {
|
|
7764
8265
|
const state = useStore((store) => store.byTab[tabId]);
|
|
7765
8266
|
const bodyRef = (0, react.useRef)(null);
|
|
7766
8267
|
const scrollTopRef = (0, react.useRef)(0);
|
|
@@ -7801,19 +8302,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7801
8302
|
},
|
|
7802
8303
|
t
|
|
7803
8304
|
};
|
|
8305
|
+
const legacy = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
8306
|
+
className: css$1.level,
|
|
8307
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Level, {
|
|
8308
|
+
path: state.root,
|
|
8309
|
+
tree
|
|
8310
|
+
})
|
|
8311
|
+
});
|
|
8312
|
+
const content = nativeTree === void 0 ? legacy : nativeTree("sidebar.files.tree", nativeTreeInput(state, (failure) => failureLine(t, failure), tree.onToggle, tree.onOpen), { fallback: legacy });
|
|
7804
8313
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7805
8314
|
ref: bodyRef,
|
|
7806
8315
|
className: css$1.body,
|
|
7807
8316
|
onScroll: (event) => {
|
|
7808
8317
|
scrollTopRef.current = event.currentTarget.scrollTop;
|
|
7809
8318
|
},
|
|
7810
|
-
children:
|
|
7811
|
-
className: css$1.level,
|
|
7812
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Level, {
|
|
7813
|
-
path: state.root,
|
|
7814
|
-
tree
|
|
7815
|
-
})
|
|
7816
|
-
})
|
|
8319
|
+
children: content
|
|
7817
8320
|
});
|
|
7818
8321
|
}
|
|
7819
8322
|
//#endregion
|
|
@@ -7986,7 +8489,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7986
8489
|
};
|
|
7987
8490
|
}
|
|
7988
8491
|
//#endregion
|
|
7989
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-host-open-in-app@0.2.2-
|
|
8492
|
+
//#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
8493
|
var shared_exports = /* @__PURE__ */ __exportAll({
|
|
7991
8494
|
OPEN_IN_APP_APPS_PATH: () => OPEN_IN_APP_APPS_PATH,
|
|
7992
8495
|
OPEN_IN_APP_APPS_ROUTE: () => OPEN_IN_APP_APPS_ROUTE,
|
|
@@ -9067,12 +9570,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9067
9570
|
accessChosen
|
|
9068
9571
|
]);
|
|
9069
9572
|
/**
|
|
9070
|
-
* Re-register one
|
|
9071
|
-
*
|
|
9072
|
-
*
|
|
9573
|
+
* Re-register one MISSING root in place. The request carries the stored
|
|
9574
|
+
* path and deliberately NO access: `registry.add` treats the call as a
|
|
9575
|
+
* revive — it keeps the record's access, alias, and identity instead of
|
|
9073
9576
|
* creating a new registration — which is also why the root limit must not
|
|
9074
|
-
* gate this button: a revive consumes no slot
|
|
9075
|
-
*
|
|
9577
|
+
* gate this button: a revive consumes no slot. Only `missing` rows get it:
|
|
9578
|
+
* a `redirected` registration now names a different directory, and revive
|
|
9579
|
+
* never changes the grant's target — replacing it is the explicit
|
|
9580
|
+
* remove-then-add flow the redirected hint describes (ADR-0027).
|
|
9076
9581
|
*/
|
|
9077
9582
|
const reRegister = (0, react.useCallback)(async (root) => {
|
|
9078
9583
|
await mutate("add", { path: root.path });
|
|
@@ -9300,14 +9805,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9300
9805
|
className: "mrfw-stateWarn",
|
|
9301
9806
|
children: t(stateKey(root.state))
|
|
9302
9807
|
}),
|
|
9303
|
-
root.state === "
|
|
9808
|
+
root.state === "missing" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
|
|
9304
9809
|
pending: state.busy,
|
|
9305
9810
|
onClick: () => {
|
|
9306
9811
|
reRegister(root);
|
|
9307
9812
|
},
|
|
9308
9813
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconRefresh, {}),
|
|
9309
9814
|
label: t("panel.reRegister")
|
|
9310
|
-
}),
|
|
9815
|
+
}) : null,
|
|
9816
|
+
root.state === "redirected" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9817
|
+
className: "mrfw-note",
|
|
9818
|
+
children: t("panel.redirectedHint")
|
|
9819
|
+
}) : null,
|
|
9311
9820
|
root.skillsEnabled === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
|
|
9312
9821
|
pending: state.busy,
|
|
9313
9822
|
pressed: root.skillsEnabled,
|
|
@@ -9668,7 +10177,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9668
10177
|
sectionRef.current = wrapper?.closest("[data-dockkit-content]") ?? null;
|
|
9669
10178
|
const content = sectionRef.current?.dataset.dockkitContent;
|
|
9670
10179
|
setTabId(content !== void 0 && content !== "" ? content : fallbackTabId.current ??= `mrfw-${Math.random().toString(36).slice(2)}`);
|
|
9671
|
-
setPane(wrapper?.closest("[data-files-root]") ?? null);
|
|
10180
|
+
setPane(wrapper?.closest("[data-files-page]") ?? wrapper?.closest("[data-files-root]") ?? null);
|
|
9672
10181
|
}, []);
|
|
9673
10182
|
const selected = (filesTree?.useTreeSelection ?? noTreeSelection)((selection) => tabId === void 0 ? void 0 : selection[tabId]) ?? "primary";
|
|
9674
10183
|
const selectRoot = filesTree?.selectRoot;
|
|
@@ -9867,7 +10376,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9867
10376
|
start: filesTree.face.start,
|
|
9868
10377
|
toggle: filesTree.face.toggle,
|
|
9869
10378
|
onOpen: filesTree.openFile,
|
|
9870
|
-
t: filesTree.t
|
|
10379
|
+
t: filesTree.t,
|
|
10380
|
+
nativeTree: pane.hasAttribute("data-files-page") ? props.nativeTree : void 0
|
|
9871
10381
|
}), pane) : null,
|
|
9872
10382
|
dialogOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkspaceFoldersDialog, {
|
|
9873
10383
|
panel: props.panel,
|
|
@@ -9990,7 +10500,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9990
10500
|
subscribeSession,
|
|
9991
10501
|
t,
|
|
9992
10502
|
openInApp: openInApp?.adapter,
|
|
9993
|
-
filesTree
|
|
10503
|
+
filesTree,
|
|
10504
|
+
nativeTree: nativeTreeRenderer(props.renderFactorySlot)
|
|
9994
10505
|
});
|
|
9995
10506
|
}));
|
|
9996
10507
|
}
|