@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyzyn/dsh-docker",
3
- "version": "0.7.1",
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.2-rc.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.2",
46
- "@hyzyn/dsh-kit": "0.4.1",
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-tools": "^0.1.2-rc.1"
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.2",
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",
@@ -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
- const scopeFor = (base) => ({
179
- get: () => ({ ...base, ...state.settingsStored }),
180
- update: async (patch) => {
181
- Object.assign(state.settingsStored, patch)
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
- events: {
202
- on: (name, listener) => {
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
- register: (ns, schema, options_) => scopeFor(options_?.base ?? {}),
232
- get: (ns) => (ns === 'tty' ? state.ttyConfig : undefined),
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 } })