dsh-auto-open-web 0.1.20 → 0.1.22
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/README.en.md +25 -9
- package/README.md +30 -9
- package/host-publish/DshAppWindow.exe +0 -0
- package/host-publish/DshAppWindow.pdb +0 -0
- package/lib/client.js +98 -28
- package/package.json +1 -2
package/README.en.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# dsh-auto-open-web
|
|
2
2
|
|
|
3
3
|
A persistent plugin for the `dsh web` profile that automatically opens the DSH Web GUI in an app-style
|
|
4
|
-
window (or browser tab) on profile start, with a configuration
|
|
5
|
-
|
|
4
|
+
window (or browser tab) on profile start, with a configuration form (manually maintained
|
|
5
|
+
browser path, etc.). On dsh ≥ 0.1.5 that entry point is the bundle's detail page on the
|
|
6
|
+
**Plugins page**; on rc.7–0.1.4 it is the **Settings → Plugin configuration** card.
|
|
6
7
|
|
|
7
8
|
## Behavior
|
|
8
9
|
|
|
@@ -83,8 +84,17 @@ cleanup.
|
|
|
83
84
|
|
|
84
85
|
Two equivalent ways:
|
|
85
86
|
|
|
86
|
-
1. **Settings
|
|
87
|
-
(
|
|
87
|
+
1. **Settings form** (recommended):
|
|
88
|
+
- **dsh ≥ 0.1.5 (incl. 0.1.6-alpha)**: open the **Plugins page → select this bundle
|
|
89
|
+
(`dsh-auto-open-web`)**; the form renders on the bundle's detail page between its
|
|
90
|
+
description and its rows (slot `plugins.bundle.config`, routed by bundle package
|
|
91
|
+
name). In this shape only **Save** is offered — leaving the page drops unsaved
|
|
92
|
+
staged edits.
|
|
93
|
+
- **rc.7 – 0.1.4**: Settings → Plugin configuration → the "自动打开网页" collapsible card
|
|
94
|
+
(slot `settings.plugin.item`). Both slots are registered at once and whichever
|
|
95
|
+
exists wins, so one package serves both generations.
|
|
96
|
+
|
|
97
|
+
Both shapes edit
|
|
88
98
|
`appWindow` (independent app window), `windowKind` (WebView2 host / browser app window),
|
|
89
99
|
`browserPath` (browser executable, with a native "Browse" file dialog; located below the
|
|
90
100
|
window-type field and enabled only when "Browser app window" is selected),
|
|
@@ -166,8 +176,12 @@ dsh plugin --profile web remove dsh-auto-open-web # removes the dependency and
|
|
|
166
176
|
After installation: pnpm adds the package to `profiles/web/node_modules`, and `dsh` appends
|
|
167
177
|
`dsh-auto-open-web` to `dsh.profile.bundles`; at startup the bundle's `cordis.patch.yml` inserts the
|
|
168
178
|
plugin row (`name: auto-open-web`, resolved by package name). After restarting `dsh web`, the
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
configuration form shows up at the matching entry point (dsh ≥ 0.1.5: the `dsh-auto-open-web`
|
|
180
|
+
bundle's detail page on the Plugins page; earlier versions: the Settings → Plugin configuration
|
|
181
|
+
card). The client bundle is scanned into the browser manifest at startup via the modules line,
|
|
182
|
+
per the `dsh.client` declaration; on the client the plugin registers into **both**
|
|
183
|
+
`plugins.bundle.config` (new) and `settings.plugin.item` (old), and the slot machinery decides
|
|
184
|
+
which one takes effect (a slot that does not exist stays pending — no error, no interference).
|
|
171
185
|
|
|
172
186
|
The effective configuration is composed layer by layer in this order (later layers win per row,
|
|
173
187
|
replacing the whole row's config rather than deep-merging): each bundle's patch (in bundles list
|
|
@@ -180,9 +194,11 @@ without touching the package.
|
|
|
180
194
|
- **Zero dependencies**: every runtime dependency is provided by the **DSH deployment** and
|
|
181
195
|
declared as an optional peer (no install warnings):
|
|
182
196
|
- `@deepseek-ai/dsh` (the host; declares the compatibility range `>=0.1.0-rc.8 <0.2.0` —
|
|
183
|
-
|
|
184
|
-
`dsh-client-runtime
|
|
185
|
-
|
|
197
|
+
the client half resolves the snapshot store across generations
|
|
198
|
+
(`@deepseek-ai/dsh-client-store` → `@deepseek-ai/dsh-client-runtime` → built-in
|
|
199
|
+
fallback) and registers into both the current plugin-manager slot
|
|
200
|
+
(`plugins.bundle.config`) and the earlier settings slot (`settings.plugin.item`);
|
|
201
|
+
no runtime version check is performed)
|
|
186
202
|
- `@deepseek-ai/schemastery` (config schema validator; resolved at runtime: normal import
|
|
187
203
|
first, then the DSH deployment copy under the Windows global npm layout)
|
|
188
204
|
- `koffi` (Windows only: Job Object / process verification / native file dialog; same runtime
|
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
> English: [README.en.md](README.en.md)
|
|
4
4
|
|
|
5
5
|
dsh web profile 启动后自动打开独立应用窗口(或网页标签页)的常驻插件,并在
|
|
6
|
-
|
|
6
|
+
设置界面提供配置表单(手动维护浏览器位置等)。dsh ≥ 0.1.5 的配置入口是
|
|
7
|
+
**「插件管理」页里本 bundle 的详情页**;rc.7–0.1.4 为**设置 → 插件配置**卡片。
|
|
7
8
|
|
|
8
9
|
## 行为
|
|
9
10
|
|
|
@@ -78,15 +79,23 @@ Job Object(强杀也生效)+ 退出清理结束进程树。
|
|
|
78
79
|
|
|
79
80
|
两种途径,等价:
|
|
80
81
|
|
|
81
|
-
1.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
1. **设置表单**(推荐):
|
|
83
|
+
- **dsh ≥ 0.1.5(含 0.1.6-alpha)**:**「插件管理」页 → 选中本插件(bundle
|
|
84
|
+
`dsh-auto-open-web`)**,配置表单显示在该 bundle 详情页的说明与插件行之间
|
|
85
|
+
(插槽 `plugins.bundle.config`,按 bundle 包名路由)。此形态下只有「保存」,
|
|
86
|
+
离开页面即丢弃未保存的暂存编辑。
|
|
87
|
+
- **rc.7 – 0.1.4**:设置 → 插件配置 → 「自动打开网页」折叠卡片
|
|
88
|
+
(插槽 `settings.plugin.item`)。两代插槽**同时注册、谁存在谁生效**,
|
|
89
|
+
无需按版本切换插件。
|
|
90
|
+
|
|
91
|
+
两代都可编辑 `appWindow`(独立应用窗口)、`windowKind`(WebView2 宿主 /
|
|
92
|
+
浏览器应用窗口)、`browserPath`(浏览器可执行文件,支持「浏览」原生对话框
|
|
93
|
+
选择;位于窗口类型下方,仅选择「浏览器应用窗口」时使能)、
|
|
85
94
|
`exitOnWindowClose`(窗口关闭时退出 DSH,默认关闭)。
|
|
86
95
|
保存后经**官方 settings 域**(客户端 settingsScope)持久化到
|
|
87
96
|
settings 文档(命名空间 `auto-open-web`),首次保存后设置值优先于行配置;
|
|
88
97
|
宿主仅保留「浏览」「测试」辅助路由(官方通道无法覆盖的能力)。
|
|
89
|
-
2. **行配置**(cordis.patch.yml
|
|
98
|
+
2. **行配置**(cordis.patch.yml):作为启动种子,设置表单保存前生效。
|
|
90
99
|
|
|
91
100
|
| 字段 | 默认 | 说明 |
|
|
92
101
|
| --- | --- | --- |
|
|
@@ -157,8 +166,12 @@ dsh plugin --profile web remove dsh-auto-open-web # 同时移除依赖与对
|
|
|
157
166
|
安装后:pnpm 将包加入 `profiles/web/node_modules`,`dsh` 把
|
|
158
167
|
`dsh-auto-open-web` 追加到 `dsh.profile.bundles`;启动时 bundle 的
|
|
159
168
|
`cordis.patch.yml` 插入插件行(`name: auto-open-web`,按包名解析)。
|
|
160
|
-
重启 `dsh web`
|
|
161
|
-
|
|
169
|
+
重启 `dsh web` 后,配置表单出现在对应入口(dsh ≥ 0.1.5:「插件管理」页里
|
|
170
|
+
`dsh-auto-open-web` bundle 的详情页;更早版本:设置 → 插件配置卡片)。
|
|
171
|
+
客户端 bundle 由 modules 行按 `dsh.client` 声明在启动时扫描进浏览器清单;
|
|
172
|
+
插件在客户端**同时**向 `plugins.bundle.config`(新)与 `settings.plugin.item`
|
|
173
|
+
(旧)两个插槽注册,由客户端插槽机制决定哪个生效(不存在者保持 pending,
|
|
174
|
+
不报错、不影响另一者)。
|
|
162
175
|
|
|
163
176
|
生效配置按以下顺序逐层组合(后应用的层按行胜出,整行替换 config 而非深合并):
|
|
164
177
|
每个 bundle 的 patch(按 bundles 列表顺序)→ profile 自己的
|
|
@@ -184,8 +197,16 @@ dsh plugin --profile web remove dsh-auto-open-web # 同时移除依赖与对
|
|
|
184
197
|
(不 require `dsh-client-ui-primitives`,不复刻官方样式表),卡片外壳、
|
|
185
198
|
字段、按钮、输入框、图标全部手写;观感经官方设计令牌变量
|
|
186
199
|
(`--dsw-alias-*` / `--dsw-static-*`)对齐,浅/深色自动跟随主题。
|
|
200
|
+
**维护提示(0.1.22)**:主按钮(保存)必须用**随主题反转**的令牌对
|
|
201
|
+
`background:var(--dsw-alias-label-primary)` +
|
|
202
|
+
`color:var(--dsw-alias-bg-layer-3)`(与官方 `PluginConfigForm` 的 save 同款)。
|
|
203
|
+
深色模式下 `--dsw-alias-brand-primary` 是**近白色**,若沿用不存在的
|
|
204
|
+
`--dsw-alias-label-inverse`(回退 #fff)会渲染成白字白底、按钮不可见;
|
|
205
|
+
同理不要引用并不存在的 `--dsw-alias-label-error`(真名是
|
|
206
|
+
`--dsw-alias-state-error-primary`)。这两条已由 `smoke-client-slots.mjs`
|
|
207
|
+
断言守护。
|
|
187
208
|
仅使用官方公开的数据/机制接口:`settingsScope`(settings 域)、`slots`
|
|
188
|
-
(插槽)、`locale`(文案)
|
|
209
|
+
(插槽)、`locale`(文案)、快照 store(跨版本解析)。
|
|
189
210
|
- **npm 包已含 WebView2 宿主编译产物**(prepack 编译后发布);**GitHub
|
|
190
211
|
main 分支与源码 checkout 方式不含** `host-publish/`(构建产物被
|
|
191
212
|
.gitignore 忽略):webview2 模式需先在 `node_modules/dsh-auto-open-web`
|
|
Binary file
|
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
// dsh-auto-open-web — Client bundle(
|
|
1
|
+
// dsh-auto-open-web — Client bundle(设置表单;UI 完全自绘,不依赖官方组件/CSS 模板)
|
|
2
2
|
// 格式:window.__ModuleLoader__.load({ id, factory });factory(require) 的
|
|
3
|
-
// require
|
|
4
|
-
//
|
|
3
|
+
// require 解析浏览器端冻结模块表(react、@deepseek-ai/dsh-client-store 等)。
|
|
4
|
+
// **不** require @deepseek-ai/dsh-client-ui-primitives 等官方 UI 包。
|
|
5
5
|
//
|
|
6
|
-
// 依赖边界(
|
|
7
|
-
// - settingsScope:官方 settings 域(命名空间 `auto-open-web
|
|
8
|
-
//
|
|
9
|
-
//
|
|
6
|
+
// 依赖边界(与官方数据的对接面,均为公开接口):
|
|
7
|
+
// - settingsScope:官方 settings 域(命名空间 `auto-open-web`)
|
|
8
|
+
// - slots:**两代插槽各自注册,谁存在谁生效**(都用 slots.inject 挂载,
|
|
9
|
+
// 不存在的插槽只会保持 pending,不会报错):
|
|
10
|
+
// · dsh ≥0.1.5:插件设置搬到「插件管理」页,bundle 配置槽
|
|
11
|
+
// `plugins.bundle.config`(按 **bundle 包名** keyed,只渲染 view:'page')
|
|
12
|
+
// · rc.7–0.1.4:设置页插件配置卡片 `settings.plugin.item`
|
|
13
|
+
// (按设置命名空间 keyed,label 供列表显示)
|
|
10
14
|
// - locale:文案注册(zh/en/ja/ko/fr/de/ru,跟随界面语言)
|
|
11
|
-
// -
|
|
15
|
+
// - store:createSnapshotStore 快照 store(解析顺序 dsh-client-store →
|
|
16
|
+
// dsh-client-runtime → 内置最小实现)
|
|
12
17
|
//
|
|
13
18
|
// 视觉(全部自产):
|
|
14
19
|
// - 卡片外壳、字段、按钮、输入框、复选/单选、徽章、图标均为手写实现;
|
|
@@ -44,13 +49,17 @@ window.__ModuleLoader__.load({
|
|
|
44
49
|
'.aow-cardReadOnly{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:12px 0 0;font-size:12px;line-height:1.5}' +
|
|
45
50
|
'.aow-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}' +
|
|
46
51
|
'.aow-cardFooter{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}' +
|
|
47
|
-
'.aow-cardFailed{min-width:0;color:var(--dsw-alias-
|
|
52
|
+
'.aow-cardFailed{min-width:0;color:var(--dsw-alias-state-error-primary);flex:1;margin:0;font-size:12px;line-height:1.5}' +
|
|
48
53
|
// 按钮:描边(outline)与主色(save)两种,禁用半透明。
|
|
49
54
|
'.aow-btn{appearance:none;font:inherit;cursor:pointer;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5;border:1px solid transparent}' +
|
|
50
55
|
'.aow-btn:disabled{opacity:.55;cursor:default}' +
|
|
51
56
|
'.aow-btnOutline{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}' +
|
|
52
57
|
'.aow-btnOutline:hover:not(:disabled){color:var(--dsw-alias-label-primary)}' +
|
|
53
|
-
|
|
58
|
+
// 主按钮(保存):与官方 PluginConfigForm 的 save 同款配色 ——
|
|
59
|
+
// 底色 label-primary、文字 bg-layer-3,深色模式下这对令牌自动反转
|
|
60
|
+
// (浅色=近黑底白字,深色=近白底深字);不再引用并不存在的 label-inverse
|
|
61
|
+
// (深色下它会退化成 #fff,造成白字白底、保存按钮看不见)。
|
|
62
|
+
'.aow-btnPrimary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3,#fff);font-weight:600}' +
|
|
54
63
|
'.aow-btnPrimary:hover:not(:disabled){filter:brightness(.95)}'
|
|
55
64
|
// 字段区:label 行 + 控件 + hint;相邻字段以 l2 分隔;徽章/恢复默认同观感。
|
|
56
65
|
var FIELDS_CSS =
|
|
@@ -66,8 +75,8 @@ window.__ModuleLoader__.load({
|
|
|
66
75
|
'.aow-input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}' +
|
|
67
76
|
'.aow-input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}' +
|
|
68
77
|
'.aow-input:disabled{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));cursor:default}' +
|
|
69
|
-
'.aow-inputInvalid{border-color:var(--dsw-alias-
|
|
70
|
-
'.aow-invalid{color:var(--dsw-alias-
|
|
78
|
+
'.aow-inputInvalid{border-color:var(--dsw-alias-state-error-primary)}' +
|
|
79
|
+
'.aow-invalid{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:1.5}' +
|
|
71
80
|
'.aow-hint{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:0;font-size:12px;line-height:1.5}'
|
|
72
81
|
// 布局与杂项:行排列、复选/单选、测试结果状态。
|
|
73
82
|
var CONTROLS_CSS =
|
|
@@ -76,7 +85,7 @@ window.__ModuleLoader__.load({
|
|
|
76
85
|
'.aow-check input{accent-color:var(--dsw-alias-brand-primary);width:15px;height:15px;margin:0;flex:none}' +
|
|
77
86
|
'.aow-check input:disabled{cursor:default}' +
|
|
78
87
|
'.aow-test-ok{color:var(--dsw-alias-state-success-primary);margin:4px 0 0;font-size:12px;line-height:1.5}' +
|
|
79
|
-
'.aow-test-fail{color:var(--dsw-alias-
|
|
88
|
+
'.aow-test-fail{color:var(--dsw-alias-state-error-primary);margin:4px 0 0;font-size:12px;line-height:1.5}'
|
|
80
89
|
var CARD_TAG = 'dsh-auto-open-web/Card.module.css'
|
|
81
90
|
var FIELDS_TAG = 'dsh-auto-open-web/Fields.module.css'
|
|
82
91
|
var CONTROLS_TAG = 'dsh-auto-open-web/Controls.module.css'
|
|
@@ -458,13 +467,25 @@ window.__ModuleLoader__.load({
|
|
|
458
467
|
}
|
|
459
468
|
}
|
|
460
469
|
|
|
461
|
-
// ──
|
|
470
|
+
// ── 设置表单(同一组件服务两代插槽) ──────────────────────────────────
|
|
471
|
+
// · 新版 plugins.bundle.config:页面传 view:'page',只出表单本体
|
|
472
|
+
// (标题/面包屑/图标由页面自绘),无折叠外壳、无"放弃"按钮,
|
|
473
|
+
// 离开页面即丢弃暂存编辑 —— 与官方 PluginConfigForm 的约定一致。
|
|
474
|
+
// · 旧版 settings.plugin.item:无 view,渲染自带折叠外壳的卡片
|
|
475
|
+
// (标题/描述/未保存标记/放弃/保存)。
|
|
462
476
|
function AutoOpenSettingsPage(props) {
|
|
463
477
|
const { t } = props
|
|
464
478
|
const state = props.useAutoOpenCard((snapshot) => snapshot)
|
|
465
479
|
const [picking, setPicking] = React.useState(false)
|
|
466
480
|
const [testing, setTesting] = React.useState(false)
|
|
467
481
|
const [testResult, setTestResult] = React.useState(null) // { ok, text } | null
|
|
482
|
+
const isPage = props.view === 'page'
|
|
483
|
+
// 新版页面表单:卸载即丢弃暂存编辑(官方同约定);用 ref 持有最新 discard。
|
|
484
|
+
const discardRef = React.useRef(props.discard)
|
|
485
|
+
discardRef.current = props.discard
|
|
486
|
+
React.useEffect(() => () => {
|
|
487
|
+
if (isPage) discardRef.current()
|
|
488
|
+
}, [])
|
|
468
489
|
|
|
469
490
|
const browse = () => {
|
|
470
491
|
if (!state.writable || picking) return
|
|
@@ -511,22 +532,22 @@ window.__ModuleLoader__.load({
|
|
|
511
532
|
onReset: () => props.resetField(field)
|
|
512
533
|
})
|
|
513
534
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
},
|
|
522
|
-
// ---- 独立应用窗口 ----
|
|
535
|
+
// 插件管理页要一行摘要时(summary 视图;bundle 配置通常只取 page,
|
|
536
|
+
// 此处按官方卡片同约定兜底)。
|
|
537
|
+
if (props.view === 'summary') return t('description')
|
|
538
|
+
|
|
539
|
+
// ---- 字段(两代插槽共用;key 供列表渲染) ----
|
|
540
|
+
const fields = [
|
|
541
|
+
// 独立应用窗口
|
|
523
542
|
React.createElement(Field, {
|
|
543
|
+
key: 'appWindow',
|
|
524
544
|
label: t('appWindow'),
|
|
525
545
|
badges: badgesFor('appWindow'),
|
|
526
546
|
control: React.createElement(Checkbox, { checked: state.appWindow.text === true, disabled: !state.writable, onChange: (v) => props.edit('appWindow', v) }, t('appWindowHint'))
|
|
527
547
|
}),
|
|
528
|
-
//
|
|
548
|
+
// 窗口类型
|
|
529
549
|
React.createElement(Field, {
|
|
550
|
+
key: 'windowKind',
|
|
530
551
|
label: t('windowKind'),
|
|
531
552
|
badges: badgesFor('windowKind'),
|
|
532
553
|
control: React.createElement(React.Fragment, null,
|
|
@@ -534,8 +555,9 @@ window.__ModuleLoader__.load({
|
|
|
534
555
|
React.createElement(Radio, { checked: state.windowKind.text === 'browser', disabled: !state.writable, value: 'browser', onChange: (v) => props.edit('windowKind', v) }, t('windowKindBrowser'))
|
|
535
556
|
)
|
|
536
557
|
}),
|
|
537
|
-
//
|
|
558
|
+
// 浏览器可执行文件(输入 + 浏览/测试按钮)
|
|
538
559
|
React.createElement(Field, {
|
|
560
|
+
key: 'browserPath',
|
|
539
561
|
label: t('browserPath'),
|
|
540
562
|
badges: badgesFor('browserPath'),
|
|
541
563
|
hint: t('browserPathHint'),
|
|
@@ -559,8 +581,9 @@ window.__ModuleLoader__.load({
|
|
|
559
581
|
)
|
|
560
582
|
: null
|
|
561
583
|
}),
|
|
562
|
-
//
|
|
584
|
+
// 窗口关闭时退出 DSH(实验性)
|
|
563
585
|
React.createElement(Field, {
|
|
586
|
+
key: 'exitOnWindowClose',
|
|
564
587
|
label: t('exitOnWindowClose'),
|
|
565
588
|
badges: React.createElement(FieldBadges, {
|
|
566
589
|
static: t('experimental'),
|
|
@@ -572,17 +595,48 @@ window.__ModuleLoader__.load({
|
|
|
572
595
|
}),
|
|
573
596
|
control: React.createElement(Checkbox, { checked: state.exitOnWindowClose.text === true, disabled: !state.writable, onChange: (v) => props.edit('exitOnWindowClose', v) }, t('exitOnWindowCloseHint'))
|
|
574
597
|
})
|
|
575
|
-
|
|
598
|
+
]
|
|
599
|
+
|
|
600
|
+
// ---- 新版:插件管理页的 bundle 配置表单(view:'page') ----
|
|
601
|
+
// 页面自绘标题/面包屑,这里只出表单本体:只读提示 + 控件 + 保存
|
|
602
|
+
// (失败提示),无折叠外壳、无"放弃"按钮(离开页面自动丢弃)。
|
|
603
|
+
if (isPage) {
|
|
604
|
+
if (!state.available) {
|
|
605
|
+
return React.createElement('p', { className: 'aow-hint', role: 'status' }, t('unavailable'))
|
|
606
|
+
}
|
|
607
|
+
const blockedPage = !state.dirty || state.invalid || state.saving
|
|
608
|
+
return React.createElement('div', null,
|
|
609
|
+
!state.writable ? React.createElement('p', { className: 'aow-cardReadOnly', role: 'status' }, t('readOnly')) : null,
|
|
610
|
+
...fields,
|
|
611
|
+
React.createElement('div', { className: 'aow-cardFooter' },
|
|
612
|
+
state.failed ? React.createElement('p', { className: 'aow-cardFailed', role: 'status' }, t('saveFailed')) : null,
|
|
613
|
+
React.createElement(Btn, { variant: 'primary', disabled: blockedPage, onClick: props.save }, state.saving ? t('saving') : t('save'))
|
|
614
|
+
)
|
|
615
|
+
)
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// ---- 旧版:设置页插件配置卡片(折叠外壳 + 放弃/保存) ----
|
|
619
|
+
return React.createElement(Card, {
|
|
620
|
+
t,
|
|
621
|
+
titleKey: 'title',
|
|
622
|
+
descriptionKey: 'description',
|
|
623
|
+
state,
|
|
624
|
+
onSave: props.save,
|
|
625
|
+
onDiscard: props.discard
|
|
626
|
+
}, ...fields)
|
|
576
627
|
}
|
|
577
628
|
|
|
578
629
|
// ---- 文案(locale 机制,zh/en/ja/ko/fr/de/ru) ----
|
|
579
630
|
const NS = 'auto-open-web'
|
|
631
|
+
/** bundle 包名:新版插件管理页按包名路由 bundle 配置,即 plugins.bundle.config 的 key。 */
|
|
632
|
+
const BUNDLE_NAME = 'dsh-auto-open-web'
|
|
580
633
|
const en = {
|
|
581
634
|
title: 'Auto-open web',
|
|
582
635
|
description: 'Open the DSH Web GUI in an app-style window on profile start; the browser path can be configured manually.',
|
|
583
636
|
save: 'Save', saving: 'Saving…', discard: 'Discard', unsaved: 'Unsaved',
|
|
584
637
|
readOnly: 'This deployment stores settings read-only.',
|
|
585
638
|
saveFailed: 'The deployment did not accept these values; they were left for you to correct.',
|
|
639
|
+
unavailable: 'This deployment does not serve these settings, so nothing can be configured here.',
|
|
586
640
|
expand: 'Show settings', collapse: 'Hide settings',
|
|
587
641
|
overridden: 'Overridden', reset: 'Reset to default',
|
|
588
642
|
appWindow: 'Independent app window',
|
|
@@ -606,6 +660,7 @@ window.__ModuleLoader__.load({
|
|
|
606
660
|
save: '保存', saving: '保存中…', discard: '放弃修改', unsaved: '未保存',
|
|
607
661
|
readOnly: '本部署的设置为只读。',
|
|
608
662
|
saveFailed: '本部署没有接受这些值,已保留供你修改。',
|
|
663
|
+
unavailable: '本部署未提供该设置命名空间,暂时无法在此配置。',
|
|
609
664
|
expand: '展开设置', collapse: '收起设置',
|
|
610
665
|
overridden: '已覆盖', reset: '恢复默认',
|
|
611
666
|
appWindow: '独立应用窗口',
|
|
@@ -629,6 +684,7 @@ window.__ModuleLoader__.load({
|
|
|
629
684
|
save: '保存', saving: '保存中…', discard: '変更を破棄', unsaved: '未保存',
|
|
630
685
|
readOnly: 'このデプロイメントの設定は読み取り専用です。',
|
|
631
686
|
saveFailed: 'デプロイメントがこの値を受け入れませんでした。修正用に保持されています。',
|
|
687
|
+
unavailable: 'このデプロイメントはこの設定を提供していないため、ここでは構成できません。',
|
|
632
688
|
expand: '設定を表示', collapse: '設定を隠す',
|
|
633
689
|
overridden: '上書き済み', reset: 'デフォルトに戻す',
|
|
634
690
|
appWindow: '独立アプリウィンドウ',
|
|
@@ -652,6 +708,7 @@ window.__ModuleLoader__.load({
|
|
|
652
708
|
save: '저장', saving: '저장 중…', discard: '변경 취소', unsaved: '저장 안 됨',
|
|
653
709
|
readOnly: '이 배포의 설정은 읽기 전용입니다.',
|
|
654
710
|
saveFailed: '배포가 이 값을 수락하지 않았습니다. 수정할 수 있도록 유지됩니다.',
|
|
711
|
+
unavailable: '이 배포는 이 설정을 제공하지 않아 여기에서 구성할 수 없습니다.',
|
|
655
712
|
expand: '설정 표시', collapse: '설정 숨기기',
|
|
656
713
|
overridden: '재정의됨', reset: '기본값으로 재설정',
|
|
657
714
|
appWindow: '독립 앱 창',
|
|
@@ -675,6 +732,7 @@ window.__ModuleLoader__.load({
|
|
|
675
732
|
save: 'Enregistrer', saving: 'Enregistrement…', discard: 'Annuler les modifications', unsaved: 'Non enregistré',
|
|
676
733
|
readOnly: 'Les paramètres de ce déploiement sont en lecture seule.',
|
|
677
734
|
saveFailed: "Le déploiement n'a pas accepté ces valeurs; elles ont été conservées pour correction.",
|
|
735
|
+
unavailable: "Ce déploiement ne fournit pas ces paramètres ; ils ne peuvent pas être configurés ici.",
|
|
678
736
|
expand: 'Afficher les paramètres', collapse: 'Masquer les paramètres',
|
|
679
737
|
overridden: 'Remplacé', reset: 'Rétablir la valeur par défaut',
|
|
680
738
|
appWindow: "Fenêtre d'application indépendante",
|
|
@@ -698,6 +756,7 @@ window.__ModuleLoader__.load({
|
|
|
698
756
|
save: 'Speichern', saving: 'Speichern…', discard: 'Änderungen verwerfen', unsaved: 'Nicht gespeichert',
|
|
699
757
|
readOnly: 'Die Einstellungen dieser Bereitstellung sind schreibgeschützt.',
|
|
700
758
|
saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert; sie wurden zur Korrektur beibehalten.',
|
|
759
|
+
unavailable: 'Diese Bereitstellung stellt diese Einstellungen nicht bereit; sie können hier nicht konfiguriert werden.',
|
|
701
760
|
expand: 'Einstellungen anzeigen', collapse: 'Einstellungen ausblenden',
|
|
702
761
|
overridden: 'Überschrieben', reset: 'Standard wiederherstellen',
|
|
703
762
|
appWindow: 'Eigenständiges App-Fenster',
|
|
@@ -721,6 +780,7 @@ window.__ModuleLoader__.load({
|
|
|
721
780
|
save: 'Сохранить', saving: 'Сохранение…', discard: 'Отменить изменения', unsaved: 'Не сохранено',
|
|
722
781
|
readOnly: 'Настройки этого развёртывания доступны только для чтения.',
|
|
723
782
|
saveFailed: 'Развёртывание не приняло эти значения; они оставлены для исправления.',
|
|
783
|
+
unavailable: 'Это развёртывание не предоставляет эти настройки; здесь их настроить нельзя.',
|
|
724
784
|
expand: 'Показать настройки', collapse: 'Скрыть настройки',
|
|
725
785
|
overridden: 'Переопределено', reset: 'Вернуть по умолчанию',
|
|
726
786
|
appWindow: 'Независимое окно приложения',
|
|
@@ -745,7 +805,17 @@ window.__ModuleLoader__.load({
|
|
|
745
805
|
// 数据通道:settingsScope(官方 settings 域)
|
|
746
806
|
const scope = ctx.settingsScope.bind({ namespace: 'auto-open-web' })
|
|
747
807
|
const controller = new AutoOpenCardController(scope)
|
|
748
|
-
//
|
|
808
|
+
// ── 新版(dsh ≥0.1.5):插件管理页 → bundle 配置槽 ──────────────────
|
|
809
|
+
// 页面按包名路由(ledger.bundles.has(pkg.name)),故 key 必须是 **bundle 包名**;
|
|
810
|
+
// 只渲染 view:'page'(标题/图标/面包屑由页面自绘),组件见 AutoOpenSettingsPage。
|
|
811
|
+
ctx.slots.inject('plugins.bundle.config', () =>
|
|
812
|
+
ctx.slots.register(
|
|
813
|
+
{ name: 'plugins.bundle.config', key: BUNDLE_NAME, locale: NS, inject: () => controller.inject() },
|
|
814
|
+
AutoOpenSettingsPage
|
|
815
|
+
)
|
|
816
|
+
)
|
|
817
|
+
// ── 旧版(rc.7–0.1.4):设置页 → 插件配置卡片 ───────────────────────
|
|
818
|
+
// 新版已移除该插槽,此处 inject 永不触发(两代互不干扰)。
|
|
749
819
|
ctx.slots.inject('settings.plugin.item', () =>
|
|
750
820
|
ctx.slots.register(
|
|
751
821
|
{ name: 'settings.plugin.item', key: 'auto-open-web', label: '自动打开网页', locale: NS, inject: () => controller.inject() },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-auto-open-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Open the DSH Web GUI in an app-style WebView2 window on profile start, with a settings card for browser paths",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"@deepseek-ai/dsh-client-connection",
|
|
28
28
|
"@deepseek-ai/dsh-api-remotes",
|
|
29
29
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
30
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
31
30
|
"@deepseek-ai/dsh-client-locale"
|
|
32
31
|
]
|
|
33
32
|
}
|