@hyzyn/dsh-docker 0.7.1 → 0.7.3
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/client-src/docker.css +13 -0
- package/client-src/index.js +18 -3
- package/client-src/session-target.js +30 -0
- package/client.js +30 -17
- package/lib/index.d.ts +13 -2
- package/lib/index.js +50 -30
- package/lib/index.js.map +1 -1
- package/package.json +13 -6
- package/scripts/route-smoke.mjs +30 -19
- package/scripts/smoke.mjs +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyzyn/dsh-docker",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "DSH Web GUI 的 Docker 容器面板插件:本机或 SSH 主机上的容器列表 / 启停删 / 日志 / 统计 / 镜像 / 一次性 exec,默认只读,配套只读优先的 agent 工具。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -31,26 +31,28 @@
|
|
|
31
31
|
"./package.json": "./package.json"
|
|
32
32
|
},
|
|
33
33
|
"dsh": {
|
|
34
|
+
"manifestVersion": 1,
|
|
34
35
|
"bundle": {
|
|
35
36
|
"patch": "./cordis.patch.yml"
|
|
36
37
|
},
|
|
37
38
|
"engines": {
|
|
38
|
-
"dsh": ">=0.1.
|
|
39
|
+
"dsh": ">=0.1.7-rc.1"
|
|
39
40
|
},
|
|
40
41
|
"client": {
|
|
41
42
|
"platform": "web"
|
|
42
43
|
}
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
46
|
-
"@hyzyn/dsh-kit": "0.4.
|
|
46
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
47
|
+
"@hyzyn/dsh-kit": "0.4.2",
|
|
47
48
|
"ssh2": "^1.17.0"
|
|
48
49
|
},
|
|
49
50
|
"peerDependencies": {
|
|
50
|
-
"@deepseek-ai/dsh
|
|
51
|
+
"@deepseek-ai/dsh": "^0.1.7-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-rc.1"
|
|
51
53
|
},
|
|
52
54
|
"devDependencies": {
|
|
53
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
55
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
54
56
|
"@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1",
|
|
55
57
|
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
56
58
|
"@types/node": "^22.20.0",
|
|
@@ -79,6 +81,11 @@
|
|
|
79
81
|
"publishConfig": {
|
|
80
82
|
"access": "public"
|
|
81
83
|
},
|
|
84
|
+
"peerDependenciesMeta": {
|
|
85
|
+
"@deepseek-ai/dsh": {
|
|
86
|
+
"optional": true
|
|
87
|
+
}
|
|
88
|
+
},
|
|
82
89
|
"scripts": {
|
|
83
90
|
"build": "tsc -p tsconfig.json && node scripts/build-client.mjs",
|
|
84
91
|
"typecheck": "tsc --noEmit && node ../../scripts/client-lint.mjs",
|
package/scripts/route-smoke.mjs
CHANGED
|
@@ -173,19 +173,26 @@ function makeCtx(config, options = {}) {
|
|
|
173
173
|
settingsStored: {},
|
|
174
174
|
ttyConfig: options.ttyConfig,
|
|
175
175
|
disposers: [],
|
|
176
|
+
/**
|
|
177
|
+
* 本插件 entry 的安装级配置(= apply 拿到的 config)。DSH ≥0.1.7 的
|
|
178
|
+
* `settings.describe()` 返回的是「默认值 ← 组合 base ← 用户层」的 resolved 值,
|
|
179
|
+
* 这里用 base ∪ settingsStored 模拟同一件事。
|
|
180
|
+
*/
|
|
181
|
+
baseConfig: config,
|
|
176
182
|
}
|
|
177
183
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// 真实实现会 emit settings/updated;这里同步触发,验证热更新路径
|
|
183
|
-
const listeners = state.listeners.get('settings/updated') ?? []
|
|
184
|
-
for (const listener of listeners) listener('docker', { ...base, ...state.settingsStored }, undefined, 'update')
|
|
185
|
-
},
|
|
186
|
-
})
|
|
184
|
+
/** loader 检出 volatile-only 变更后发的事件(测试里同步发,验证热更新路径)。 */
|
|
185
|
+
const emitVolatile = () => {
|
|
186
|
+
for (const listener of state.listeners.get('loader/volatile-update') ?? []) listener()
|
|
187
|
+
}
|
|
187
188
|
|
|
188
189
|
const makeChild = (names) => {
|
|
190
|
+
const on = (name, listener) => {
|
|
191
|
+
const list = state.listeners.get(name) ?? []
|
|
192
|
+
list.push(listener)
|
|
193
|
+
state.listeners.set(name, list)
|
|
194
|
+
return () => {}
|
|
195
|
+
}
|
|
189
196
|
const child = {
|
|
190
197
|
logger: { info: () => {}, warn: () => {} },
|
|
191
198
|
effect: (callback, _name) => {
|
|
@@ -198,14 +205,8 @@ function makeCtx(config, options = {}) {
|
|
|
198
205
|
cb(grand)
|
|
199
206
|
return () => {}
|
|
200
207
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const list = state.listeners.get(name) ?? []
|
|
204
|
-
list.push(listener)
|
|
205
|
-
state.listeners.set(name, list)
|
|
206
|
-
return () => {}
|
|
207
|
-
},
|
|
208
|
-
},
|
|
208
|
+
on,
|
|
209
|
+
events: { on },
|
|
209
210
|
}
|
|
210
211
|
if (names.includes('tools')) {
|
|
211
212
|
child.tools = {
|
|
@@ -227,9 +228,19 @@ function makeCtx(config, options = {}) {
|
|
|
227
228
|
}
|
|
228
229
|
}
|
|
229
230
|
if (names.includes('settings')) {
|
|
231
|
+
// DSH ≥0.1.7 的 settings 服务(SettingsForms):describe / update / configure。
|
|
232
|
+
// describe 里额外放一个 tty entry,模拟「tty 已安装、连接簿可读」。
|
|
230
233
|
child.settings = {
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
describe: () => [
|
|
235
|
+
{ ns: 'docker', value: { ...state.baseConfig, ...state.settingsStored } },
|
|
236
|
+
...(state.ttyConfig === undefined ? [] : [{ ns: 'tty', value: state.ttyConfig }]),
|
|
237
|
+
],
|
|
238
|
+
update: async (ns, patch) => {
|
|
239
|
+
if (ns !== 'docker') throw new Error('未知的 entry: ' + ns)
|
|
240
|
+
Object.assign(state.settingsStored, patch)
|
|
241
|
+
emitVolatile()
|
|
242
|
+
},
|
|
243
|
+
configure: () => () => {},
|
|
233
244
|
}
|
|
234
245
|
}
|
|
235
246
|
if (names.includes('systemPrompt')) {
|
package/scripts/smoke.mjs
CHANGED
|
@@ -662,6 +662,13 @@ test('resolveTarget:本机 / 连接簿命中 / 连接簿缺失 / 内联', () =
|
|
|
662
662
|
const missing = host.resolveTarget({ name: 'prod', kind: 'ssh', book: 'nope' }, books)
|
|
663
663
|
assert.equal(missing.resolved, undefined)
|
|
664
664
|
assert.match(missing.error, /连接簿条目不存在:nope/)
|
|
665
|
+
/*
|
|
666
|
+
* 指引必须指向用户**真能做的动作**:旧文案让用户"去 tty 终端面板的设置卡片里添加",
|
|
667
|
+
* 但那张卡片管的是 tty 自己的连接簿条目,改不了 docker 目标引用的名字——照着找只会扑空
|
|
668
|
+
* (实测:目标引用 HS-248、连接簿里只有 HS_248_ADMIN)。真正要改的是本卡片的「连接簿」下拉。
|
|
669
|
+
*/
|
|
670
|
+
assert.match(missing.error, /本卡片/, '缺失引用时该指回本卡片的「连接簿」下拉')
|
|
671
|
+
assert.doesNotMatch(missing.error, /请在 tty 终端面板的设置卡片里添加/, '不该再让人去 tty 卡片做它做不到的事')
|
|
665
672
|
|
|
666
673
|
const inline = host.resolveTarget({ name: 'inline', kind: 'ssh', host: 'h', username: 'u' }, books)
|
|
667
674
|
assert.deepEqual(inline.resolved, { name: 'inline', kind: 'ssh', spec: { host: 'h', port: 22, username: 'u', auth: 'agent', keyPath: '', password: '', passphrase: '', agentForward: false } })
|