dsh-command-palette 0.1.1 → 0.1.2

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 CHANGED
@@ -78,6 +78,16 @@ Service API:
78
78
 
79
79
  Provider IDs must be unique. Commands require at least `id`, `title`, and `run()`; the provider ID is automatically prefixed to the final command ID.
80
80
 
81
+ Dynamic providers may also implement `subscribe(invalidate)`. Call `invalidate()` when external state changes to make the palette collect commands again. The disposer returned by `subscribe` runs automatically when the provider is removed:
82
+
83
+ ```js
84
+ {
85
+ id: 'dynamic-plugin',
86
+ collect: () => buildCommands(currentState),
87
+ subscribe: (invalidate) => externalStore.subscribe(() => invalidate())
88
+ }
89
+ ```
90
+
81
91
  Native Desktop browser tabs, Electron IPC, and native-view coordination are outside this package. A separate Desktop enhancement plugin can add them later through this API.
82
92
 
83
93
  ## Data storage
package/README.md CHANGED
@@ -78,6 +78,16 @@ exports.apply = (ctx) => {
78
78
 
79
79
  Provider ID 必须唯一。命令至少需要 `id`、`title` 和 `run()`;最终命令 ID 会自动加上 Provider 前缀。
80
80
 
81
+ 动态 Provider 可以额外实现 `subscribe(invalidate)`。当外部状态变化时调用 `invalidate()`,命令面板会重新收集命令;`subscribe` 返回的卸载函数会在 Provider 注销时自动执行:
82
+
83
+ ```js
84
+ {
85
+ id: 'dynamic-plugin',
86
+ collect: () => buildCommands(currentState),
87
+ subscribe: (invalidate) => externalStore.subscribe(() => invalidate())
88
+ }
89
+ ```
90
+
81
91
  Desktop 原生浏览器标签、Electron IPC 和原生视图协调不属于本包,后续可以由独立 Desktop 增强插件通过上述接口接入。
82
92
 
83
93
  ## 数据存储
package/client.js CHANGED
@@ -36,7 +36,10 @@ window.__ModuleLoader__.load({
36
36
  let revision = 0
37
37
  const emit = (reason) => {
38
38
  const snapshot = { open, revision: ++revision, reason }
39
- for (const listener of listeners) listener(snapshot)
39
+ for (const listener of listeners) {
40
+ try { listener(snapshot) }
41
+ catch (error) { console.warn('[dsh-command-palette] subscriber failed:', error) }
42
+ }
40
43
  }
41
44
  return {
42
45
  registerProvider(provider) {
@@ -45,15 +48,33 @@ window.__ModuleLoader__.load({
45
48
  }
46
49
  const id = provider.id.trim()
47
50
  if (providers.has(id)) throw new Error(`Command palette provider already registered: ${id}`)
48
- providers.set(id, provider)
51
+ const record = { provider, disposeSubscription: null }
52
+ providers.set(id, record)
49
53
  emit('provider-registered')
54
+ if (typeof provider.subscribe === 'function') {
55
+ try {
56
+ const dispose = provider.subscribe(() => emit('provider-updated'))
57
+ if (typeof dispose === 'function') record.disposeSubscription = dispose
58
+ } catch (error) {
59
+ console.warn(`[dsh-command-palette] provider ${id} subscription failed:`, error)
60
+ }
61
+ }
62
+ let removed = false
50
63
  return () => {
51
- if (providers.delete(id)) emit('provider-removed')
64
+ if (removed) return
65
+ removed = true
66
+ const current = providers.get(id)
67
+ if (!current) return
68
+ providers.delete(id)
69
+ try { current.disposeSubscription?.() }
70
+ catch (error) { console.warn(`[dsh-command-palette] provider ${id} disposer failed:`, error) }
71
+ emit('provider-removed')
52
72
  }
53
73
  },
54
74
  collect(context = {}) {
55
75
  const commands = []
56
- for (const [providerId, provider] of providers) {
76
+ for (const [providerId, record] of providers) {
77
+ const provider = record.provider
57
78
  const commandIds = new Set()
58
79
  let provided
59
80
  try { provided = provider.collect(context) }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-command-palette",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A keyboard-first command palette for DeepSeek Harness sessions, workspaces, settings, features, and reusable custom commands.",
5
5
  "license": "MIT",
6
6
  "author": "chenyangcun",