dsh-x-core 0.1.21 → 0.1.23

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.
Files changed (50) hide show
  1. package/assets/dsh-preview.png +0 -0
  2. package/assets/dsh.ico +0 -0
  3. package/assets/icon.ico +0 -0
  4. package/assets/tray.ico +0 -0
  5. package/assets/tray.png +0 -0
  6. package/core-npm.js +201 -183
  7. package/desktop-plugins.js +86 -0
  8. package/desktop.js +200 -0
  9. package/filemanager-base.js +7 -8
  10. package/filemanager-linux.js +124 -0
  11. package/filemanager.js +4 -7
  12. package/native-notify.js +74 -0
  13. package/node/node +2 -1
  14. package/package.json +1 -1
  15. package/packs/dsh-x-workbench/README.md +61 -0
  16. package/packs/dsh-x-workbench/dspack.json +4 -0
  17. package/packs/dsh-x-workbench/home/skills/agent-browser/LICENSE-APACHE-2.0.txt +202 -0
  18. package/packs/dsh-x-workbench/home/skills/agent-browser/NOTICE.md +6 -0
  19. package/packs/dsh-x-workbench/home/skills/agent-browser/SKILL.md +697 -0
  20. package/packs/dsh-x-workbench/home/skills/agent-browser/references/authentication.md +313 -0
  21. package/packs/dsh-x-workbench/home/skills/agent-browser/references/commands.md +300 -0
  22. package/packs/dsh-x-workbench/home/skills/agent-browser/references/profiling.md +120 -0
  23. package/packs/dsh-x-workbench/home/skills/agent-browser/references/proxy-support.md +194 -0
  24. package/packs/dsh-x-workbench/home/skills/agent-browser/references/session-management.md +201 -0
  25. package/packs/dsh-x-workbench/home/skills/agent-browser/references/snapshot-refs.md +229 -0
  26. package/packs/dsh-x-workbench/home/skills/agent-browser/references/video-recording.md +173 -0
  27. package/packs/dsh-x-workbench/home/skills/agent-browser/templates/authenticated-session.sh +105 -0
  28. package/packs/dsh-x-workbench/home/skills/agent-browser/templates/capture-workflow.sh +69 -0
  29. package/packs/dsh-x-workbench/home/skills/agent-browser/templates/form-automation.sh +62 -0
  30. package/packs/dsh-x-workbench/home/skills/electron/LICENSE-APACHE-2.0.txt +202 -0
  31. package/packs/dsh-x-workbench/home/skills/electron/NOTICE.md +6 -0
  32. package/packs/dsh-x-workbench/home/skills/electron/SKILL.md +243 -0
  33. package/packs/dsh-x-workbench/manifest.json +35 -0
  34. package/perf/patch-hooks.mjs +14 -1
  35. package/perf/plugin-profile.mjs +204 -0
  36. package/perf/register.mjs +4 -0
  37. package/platform.js +2 -1
  38. package/public/booting.html +475 -0
  39. package/public/favicon.ico +0 -0
  40. package/public/favicon.png +0 -0
  41. package/public/icon.png +0 -0
  42. package/public/index.html +9277 -8173
  43. package/public/internal-tabs.js +45 -41
  44. package/public/launcher.css +285 -98
  45. package/public/mascot.js +1 -1
  46. package/public/theme.css +33 -6
  47. package/public/water.js +1 -1
  48. package/registry.js +38 -3
  49. package/server.js +1060 -119
  50. package/settings.js +78 -1
package/settings.js CHANGED
@@ -90,6 +90,27 @@ export function updateSourceForDownload(value) {
90
90
  return safeDownloadSource(value) === 'official' ? 'direct' : 'mirror'
91
91
  }
92
92
 
93
+ /**
94
+ * 跑 dsh 用哪个 node:bundled = 启动器自带(打包后是 Electron 内嵌的 Node),
95
+ * system = 用户机器上装的那个。只影响 dsh 子进程,启动器自己始终跑在 Electron 里。
96
+ * 换档要重启启动器:platform.js 在加载时就把 RUNTIME_NODE 定成了常量。
97
+ */
98
+ export const NODE_RUNTIMES = ['bundled', 'system']
99
+ export const DEFAULT_NODE_RUNTIME = 'bundled'
100
+
101
+ export function safeNodeRuntime(value) {
102
+ const name = String(value ?? '').trim().toLowerCase()
103
+ return NODE_RUNTIMES.includes(name) ? name : DEFAULT_NODE_RUNTIME
104
+ }
105
+
106
+ /** 系统 node 的路径;空 = 从 PATH 自动找。存在性在保存时验证,这里只清空白与粘贴带上的引号。 */
107
+ export function safeSystemNodePath(value) {
108
+ const text = String(value ?? '').trim().replace(/^"(.*)"$/, '$1').trim()
109
+ if (!text) return ''
110
+ if (text.length > 4096) throw new Error('node 路径太长')
111
+ return text
112
+ }
113
+
93
114
  /**
94
115
  * 网络代理的三种模式:跟随系统(默认,自己探测系统代理)/ 手动填地址 / 不走代理。
95
116
  *
@@ -185,6 +206,19 @@ export function safeDshHome(dir) {
185
206
  return resolve(trimmed)
186
207
  }
187
208
 
209
+ /**
210
+ * 项目目录:启动项把 `DSH_HOME` 放进 `<项目>/.dsh` 时,它就是用户的项目根(也当新会话的工作目录)。
211
+ * 和用户目录分开一个校验,报错才说得清该填哪一个;两者的取值规则一样(绝对路径、去掉首尾空白)。
212
+ */
213
+ export function safeWorkdir(dir) {
214
+ if (dir === undefined || dir === null) return ''
215
+ if (typeof dir !== 'string') throw new Error('项目目录填一个路径,别填别的')
216
+ const trimmed = dir.trim()
217
+ if (!trimmed) return ''
218
+ if (!isAbsolute(trimmed)) throw new Error('请使用绝对路径(例如 D:\\projects\\demo)')
219
+ return resolve(trimmed)
220
+ }
221
+
188
222
  export function safeDshHomes(value) {
189
223
  const homes = new Map()
190
224
  for (const item of Array.isArray(value) ? value : []) {
@@ -235,6 +269,25 @@ export const DEFAULTS = {
235
269
  reduceMotion: false,
236
270
  hideBackground: false,
237
271
  hideBigFish: false,
272
+ // ---- 桌面端系统开关(Electron 外壳直接读 settings.json,见 shell/prefs.mjs)----
273
+ // Chromium 硬件加速:关闭能规避显卡/驱动导致的白屏与闪退,代价是动画更吃 CPU,重启生效
274
+ hardwareAcceleration: true,
275
+ // 发现更新就自动下载;没有 dsh 实例在跑时直接装上并重启
276
+ autoUpdate: false,
277
+ // dsh 实例启动完成 / 启动失败时发桌面通知(外壳实现)
278
+ taskNotifications: true,
279
+ // 通知是否带提示音;关掉只影响启动器自己发的通知
280
+ notificationSound: true,
281
+ // 关窗口 = 隐藏到托盘(开着才有后台实例可找回);关掉就是真退出
282
+ closeToTray: true,
283
+ // 阻止系统空闲休眠(跑长任务时用)
284
+ keepAwake: false,
285
+ // 内置浏览器(官方右侧栏浏览器):关掉后不再给新启动的 dsh 实例放开那一行插件
286
+ browserControl: true,
287
+ // 内置浏览器不校验 HTTPS 证书(自签名 / 过期证书的站点也能打开),只影响浏览器分区
288
+ browserIgnoreCertificate: false,
289
+ // 右键菜单(dsh-x-context-menu):关掉后新启动的 dsh 实例不再加载这个插件(不卸载)
290
+ contextMenu: true,
238
291
  downloadSource: DEFAULT_SOURCE,
239
292
  // 启动器更新的下载源:direct(默认)/ mirror(国内加速)
240
293
  updateSource: DEFAULT_UPDATE_SOURCE,
@@ -245,6 +298,9 @@ export const DEFAULTS = {
245
298
  openMode: DEFAULT_OPEN_MODE,
246
299
  // dsh 的用户目录(DSH_HOME)。留空 = 默认 ~/.dsh;用户把 .dsh 挪到别的盘时在这里指回去
247
300
  dshHome: '',
301
+ // 跑 dsh 用哪个 node:bundled(启动器自带,默认)/ system(系统装的那个;路径留空就按 PATH 找)
302
+ nodeRuntime: DEFAULT_NODE_RUNTIME,
303
+ systemNodePath: '',
248
304
  // 单独登记的目录不依赖启动项,删掉最后一个 Profile 后仍能回到这里新建。
249
305
  dshHomes: [],
250
306
  dshHomeNames: {},
@@ -420,6 +476,10 @@ export function safeLaunchPresets(value) {
420
476
  try { icon = safeLaunchIcon(item.icon) } catch { /* 旧设置里的坏图片退回默认图标,保留启动项。 */ }
421
477
  let dshHome = ''
422
478
  try { dshHome = safeDshHome(item.dshHome) } catch { return [] }
479
+ // 项目目录跟着启动项走:丢了它就只剩一个平平无奇的独立目录,工作目录也回不到项目根,
480
+ // 所以和 dshHome 一样,坏值宁可整条丢掉,别留下半截环境。
481
+ let workdir = ''
482
+ try { workdir = safeWorkdir(item.workdir) } catch { return [] }
423
483
  // 启动项最近用过的两个版本(当前用/上一次用):清理旧版本时按启动项保留,给回退用。
424
484
  const usedVersion = String(item.usedVersion ?? '')
425
485
  const prevVersion = String(item.prevVersion ?? '')
@@ -431,7 +491,7 @@ export function safeLaunchPresets(value) {
431
491
  ...(updateChannel !== DEFAULT_UPDATE_CHANNEL ? { updateChannel } : {}),
432
492
  ...(VERSION_RE.test(usedVersion) ? { usedVersion } : {}),
433
493
  ...(VERSION_RE.test(prevVersion) ? { prevVersion } : {}),
434
- ...(dshHome ? { dshHome } : {}), ...(icon !== 'terminal' ? { icon } : {}) }]
494
+ ...(workdir ? { workdir } : {}), ...(dshHome ? { dshHome } : {}), ...(icon !== 'terminal' ? { icon } : {}) }]
435
495
  })
436
496
  const builtin = presets.find((item) => item.id === DEFAULT_LAUNCH_ID) || { ...DEFAULT_LAUNCH }
437
497
  if (builtin.name === '默认启动') builtin.name = 'DSH'
@@ -640,12 +700,16 @@ function mergeStoredSettings(stored) {
640
700
  merged.hideBackground = stored.disableBackgroundAnimation === true
641
701
  }
642
702
  delete merged.disableBackgroundAnimation
703
+ // 更新通道开关已撤:通道跟着当前版本走,旧文件里的键顺手清掉
704
+ delete merged.acceptPrerelease
643
705
  // 内置插件的预置开关已撤(插件改由整合包分发),旧文件里的键顺手清掉
644
706
  delete merged.seedBundled
645
707
  delete merged.seedMarket
646
708
  try { merged.pluginMarketSources = safePluginMarketSources(merged.pluginMarketSources) } catch { merged.pluginMarketSources = [] }
647
709
  delete merged.seedMemory
648
710
  try { merged.keepVersions = safeKeepVersions(merged.keepVersions) } catch { merged.keepVersions = 2 }
711
+ merged.nodeRuntime = safeNodeRuntime(merged.nodeRuntime)
712
+ try { merged.systemNodePath = safeSystemNodePath(merged.systemNodePath) } catch { merged.systemNodePath = '' }
649
713
  return merged
650
714
  }
651
715
 
@@ -740,11 +804,24 @@ async function saveSettingsNow(patch) {
740
804
  merged.dshHomeNames = safeDshHomeNames(merged.dshHomeNames)
741
805
  merged.lang = 'lang' in patch ? safeLang(patch.lang) : safeLang(merged.lang)
742
806
  merged.theme = safeTheme(merged.theme)
807
+ merged.nodeRuntime = 'nodeRuntime' in patch ? safeNodeRuntime(patch.nodeRuntime) : safeNodeRuntime(merged.nodeRuntime)
808
+ merged.systemNodePath = 'systemNodePath' in patch ? safeSystemNodePath(patch.systemNodePath) : safeSystemNodePath(merged.systemNodePath)
743
809
  merged.launchIsolation = safeLaunchIsolation(merged.launchIsolation)
744
810
  merged.panelTransparency = safePanelTransparency(merged.panelTransparency)
745
811
  merged.reduceMotion = merged.reduceMotion === true
746
812
  merged.hideBackground = merged.hideBackground === true
747
813
  merged.hideBigFish = merged.hideBigFish === true
814
+ // 桌面端系统开关:只认布尔,脏值回默认(true 的两个用 !== false,其余 === true)
815
+ merged.hardwareAcceleration = merged.hardwareAcceleration !== false
816
+ merged.autoUpdate = merged.autoUpdate === true
817
+ merged.taskNotifications = merged.taskNotifications !== false
818
+ merged.notificationSound = merged.notificationSound !== false
819
+ merged.closeToTray = merged.closeToTray !== false
820
+ merged.keepAwake = merged.keepAwake === true
821
+ // 内置浏览器开关与证书校验:和上面一组同一套布尔语义
822
+ merged.browserControl = merged.browserControl !== false
823
+ merged.browserIgnoreCertificate = merged.browserIgnoreCertificate === true
824
+ merged.contextMenu = merged.contextMenu !== false
748
825
  // 同 webBind:脏值顺手修回默认(回环),显式改绑定方式时才把错误抛给调用方
749
826
  try {
750
827
  merged.webBind = safeWebBind(merged.webBind)