dsh-code-ui 1.1.3 → 1.1.4
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/lib/client.js +69 -16
- package/lib/index.js +26 -3
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1087,22 +1087,44 @@ window.__ModuleLoader__.load({
|
|
|
1087
1087
|
)
|
|
1088
1088
|
}
|
|
1089
1089
|
|
|
1090
|
-
/* ============ §8 装配与 slot
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
)
|
|
1095
|
-
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1090
|
+
/* ============ §8 装配与 slot 注册(受「启用开关」控制,可动态挂/卸载) ============ */
|
|
1091
|
+
// 开关存 host 端 settings(enabled 字段,持久化)。默认启用:
|
|
1092
|
+
// get-self 失败 / 字段缺失(旧 host)时绝不隐藏编辑器,只有明确 enabled===false 才不挂载。
|
|
1093
|
+
let unmountEditorFns = null
|
|
1094
|
+
function mountEditor() {
|
|
1095
|
+
if (unmountEditorFns) return
|
|
1096
|
+
const disposers = []
|
|
1097
|
+
disposers.push(slots.inject('conversation.session.header.actions', () => slots.register(
|
|
1098
|
+
{ name: 'conversation.session.header.actions', id: 'cdex-input-bridge', order: 9999, label: '' },
|
|
1099
|
+
(props) => h(InputBridge, props),
|
|
1100
|
+
)))
|
|
1101
|
+
disposers.push(slots.inject('shell.overlay', () => {
|
|
1102
|
+
const d1 = slots.register(
|
|
1103
|
+
{ name: 'shell.overlay', id: 'cdex-mode-tabs', order: 5, label: '界面模式' },
|
|
1104
|
+
() => h(ModeTabs, null),
|
|
1105
|
+
)
|
|
1106
|
+
const d2 = slots.register(
|
|
1107
|
+
{ name: 'shell.overlay', id: 'cdex-workbench', order: 10, label: '代码编辑器' },
|
|
1108
|
+
() => h(Workbench, null),
|
|
1109
|
+
)
|
|
1110
|
+
return () => { if (d1) d1(); if (d2) d2() }
|
|
1111
|
+
}))
|
|
1112
|
+
unmountEditorFns = () => { disposers.forEach((d) => { try { d() } catch (e) {} }) }
|
|
1113
|
+
}
|
|
1114
|
+
function unmountEditor() {
|
|
1115
|
+
if (!unmountEditorFns) return
|
|
1116
|
+
try { unmountEditorFns() } catch (e) {}
|
|
1117
|
+
unmountEditorFns = null
|
|
1118
|
+
}
|
|
1119
|
+
// 卡片里切换开关 -> set-enabled 成功后调用:立即挂/卸载编辑器(无需刷新页面、无需重启 DSH)
|
|
1120
|
+
function applyEnabled(v) {
|
|
1121
|
+
if (v) mountEditor()
|
|
1122
|
+
else unmountEditor()
|
|
1123
|
+
}
|
|
1124
|
+
// 启动时先查开关再挂载(RPC 失败 = 默认启用)
|
|
1125
|
+
callHost('get-self').then((r) => {
|
|
1126
|
+
applyEnabled(!(r && !r.error && r.enabled === false))
|
|
1127
|
+
}).catch(() => applyEnabled(true))
|
|
1106
1128
|
|
|
1107
1129
|
/* ---- 插件配置卡片(settings.plugin.item):信息 + 检查更新 / 一键更新 / 本地包更新 ---- */
|
|
1108
1130
|
function PluginConfigCard() {
|
|
@@ -1111,9 +1133,27 @@ window.__ModuleLoader__.load({
|
|
|
1111
1133
|
const [chk, setChk] = React.useState(null)
|
|
1112
1134
|
const [run, setRun] = React.useState(null)
|
|
1113
1135
|
const [localPath, setLocalPath] = React.useState('')
|
|
1136
|
+
const [enabling, setEnabling] = React.useState(false)
|
|
1114
1137
|
const lastPayloadRef = React.useRef(null)
|
|
1115
1138
|
const pollDisposeRef = React.useRef(null)
|
|
1116
1139
|
|
|
1140
|
+
// 编辑器开关:写 host settings 持久化;成功后立即挂/卸载编辑器 UI
|
|
1141
|
+
function toggleEnabled() {
|
|
1142
|
+
if (!self || enabling) return
|
|
1143
|
+
const next = self.enabled === false
|
|
1144
|
+
setEnabling(true)
|
|
1145
|
+
callHost('set-enabled', { enabled: next }).then((r) => {
|
|
1146
|
+
setEnabling(false)
|
|
1147
|
+
if (r && !r.error) {
|
|
1148
|
+
setSelf(Object.assign({}, self, { enabled: next }))
|
|
1149
|
+
applyEnabled(next)
|
|
1150
|
+
showToast(next ? '已启用编辑器(立即生效)' : '已禁用编辑器(立即生效)')
|
|
1151
|
+
} else {
|
|
1152
|
+
showToast('切换失败:' + ((r && r.error) || '未知错误'))
|
|
1153
|
+
}
|
|
1154
|
+
})
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1117
1157
|
function stopPoll() {
|
|
1118
1158
|
if (pollDisposeRef.current) { try { pollDisposeRef.current() } catch (e) {} pollDisposeRef.current = null }
|
|
1119
1159
|
}
|
|
@@ -1186,6 +1226,19 @@ window.__ModuleLoader__.load({
|
|
|
1186
1226
|
: h('span', { className: 'cdx-pc-chevron' + (cardOpen ? ' cdx-pc-chevron-open' : '') }, '▾'),
|
|
1187
1227
|
),
|
|
1188
1228
|
cardOpen ? h('div', { className: 'cdx-pc-body' },
|
|
1229
|
+
// 字段零:编辑器启用开关
|
|
1230
|
+
h('div', { className: 'cdx-pc-field' },
|
|
1231
|
+
h('div', { className: 'cdx-pc-head' },
|
|
1232
|
+
h('span', { className: 'cdx-pc-label' }, '编辑器开关(页面入口 + 编辑器整体)'),
|
|
1233
|
+
h('button', {
|
|
1234
|
+
type: 'button',
|
|
1235
|
+
className: 'cdx-pc-btn ' + (self && self.enabled !== false ? 'cdx-pc-btn-outline' : 'cdx-pc-btn-primary'),
|
|
1236
|
+
disabled: !self || enabling,
|
|
1237
|
+
onClick: toggleEnabled,
|
|
1238
|
+
}, enabling ? '切换中…' : (self && self.enabled !== false ? '已启用 · 点击禁用' : '已禁用 · 点击启用')),
|
|
1239
|
+
),
|
|
1240
|
+
h('p', { className: 'cdx-pc-note' }, '切换立即生效(实时挂载/卸载编辑器),无需重启 DSH,也无需刷新页面;若个别界面未跟着变化,普通刷新(F5)即可。开关状态持久化保存。'),
|
|
1241
|
+
),
|
|
1189
1242
|
// 字段一:在线检查更新
|
|
1190
1243
|
h('div', { className: 'cdx-pc-field' },
|
|
1191
1244
|
h('div', { className: 'cdx-pc-head' },
|
package/lib/index.js
CHANGED
|
@@ -94,16 +94,20 @@ const CODE_UI_SETTINGS_NS = settingsNamespace("dsh-code-ui");
|
|
|
94
94
|
const CodeUiSettingsSchema = z.object({
|
|
95
95
|
// 检查更新用的 registry(只影响在线「检查」;安装仍走 profile 自己的 .npmrc)
|
|
96
96
|
updateRegistry: z.string().default(REGISTRY_DEFAULT),
|
|
97
|
+
// 编辑器总开关:false 时 client 端不挂载编辑器 UI(配置卡片始终保留,可随时再开)
|
|
98
|
+
enabled: z.boolean().default(true),
|
|
97
99
|
});
|
|
98
100
|
// 解析后的当前值:settings 服务未挂载/未写入时保持默认
|
|
99
|
-
const selfSettings = { updateRegistry: REGISTRY_DEFAULT };
|
|
101
|
+
const selfSettings = { updateRegistry: REGISTRY_DEFAULT, enabled: true };
|
|
102
|
+
// settings 服务引用(「启用/禁用」开关写入用;由 installSelfSettings 捕获)
|
|
103
|
+
let settingsServiceRef = null;
|
|
100
104
|
function installSelfSettings(ctx) {
|
|
101
|
-
let source = () => ({ updateRegistry: selfSettings.updateRegistry });
|
|
105
|
+
let source = () => ({ updateRegistry: selfSettings.updateRegistry, enabled: selfSettings.enabled });
|
|
102
106
|
installSettingsSection(
|
|
103
107
|
ctx,
|
|
104
108
|
CODE_UI_SETTINGS_NS,
|
|
105
109
|
CodeUiSettingsSchema,
|
|
106
|
-
{ updateRegistry: selfSettings.updateRegistry },
|
|
110
|
+
{ updateRegistry: selfSettings.updateRegistry, enabled: selfSettings.enabled },
|
|
107
111
|
{
|
|
108
112
|
setSource: (current) => { source = current; },
|
|
109
113
|
onChange: () => {
|
|
@@ -112,10 +116,13 @@ function installSelfSettings(ctx) {
|
|
|
112
116
|
if (typeof v.updateRegistry === "string" && /^https?:\/\//.test(v.updateRegistry)) {
|
|
113
117
|
selfSettings.updateRegistry = v.updateRegistry.replace(/\/+$/, "");
|
|
114
118
|
}
|
|
119
|
+
if (typeof v.enabled === "boolean") selfSettings.enabled = v.enabled;
|
|
115
120
|
} catch (_) {}
|
|
116
121
|
},
|
|
117
122
|
},
|
|
118
123
|
);
|
|
124
|
+
// 捕获 settings 服务实例:卡片的「启用/禁用」开关经 set-enabled RPC 写入本命名空间
|
|
125
|
+
ctx.inject(["settings"], (sctx) => { settingsServiceRef = sctx.settings; });
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
async function fetchLatestVersion(name, registry) {
|
|
@@ -463,9 +470,25 @@ function rpcHandler(ctx) {
|
|
|
463
470
|
profileRoot: profileRoot,
|
|
464
471
|
workspace: profileRoot ? existsSync(join(profileRoot, "pnpm-workspace.yaml")) : false,
|
|
465
472
|
updateRegistry: selfSettings.updateRegistry,
|
|
473
|
+
enabled: selfSettings.enabled !== false,
|
|
466
474
|
});
|
|
467
475
|
}
|
|
468
476
|
|
|
477
|
+
if (endpoint === "set-enabled") {
|
|
478
|
+
if (typeof args.enabled !== "boolean") return ok({ error: "enabled 参数需为布尔值" });
|
|
479
|
+
if (!settingsServiceRef || typeof settingsServiceRef.update !== "function") {
|
|
480
|
+
return ok({ error: "settings 服务不可用,重启 DSH 后再试" });
|
|
481
|
+
}
|
|
482
|
+
try {
|
|
483
|
+
// 写入命名空间(schema 校验 + 持久化;watch 会经 onChange 再同步一次 selfSettings)
|
|
484
|
+
await settingsServiceRef.update(CODE_UI_SETTINGS_NS, { enabled: args.enabled });
|
|
485
|
+
selfSettings.enabled = args.enabled;
|
|
486
|
+
return ok({ ok: true, enabled: args.enabled });
|
|
487
|
+
} catch (err) {
|
|
488
|
+
return ok({ error: "写入设置失败:" + ((err && err.message) || String(err)) });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
469
492
|
if (endpoint === "check-update") {
|
|
470
493
|
const out = { current: SELF_VERSION, latest: null, updateAvailable: false, notPublished: false, registryUsed: null, error: null };
|
|
471
494
|
// 主源 = 设置里的 updateRegistry(默认官方源,镜像有同步滞后);主源不可达时用另一个兜底做「检查」
|