@goodandready/dsh-plugin-notify 0.4.2 → 0.4.4

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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.4.4] - 2026-10-15
8
+
9
+ ### Fixed
10
+ - **Client config form lookup** (#61): Query `ctx.configForms` strictly by canonical entry id `plugin-notify` (`ROW_ID`) rather than attempting fallback queries to scoped package name `@goodandready/dsh-plugin-notify`, fixing unresolvable configuration lookups in the settings panel.
11
+
12
+ ## [0.4.3] - 2026-10-15
13
+
14
+ ### Fixed
15
+ - **Host event cleanup** (#59): Prune dead listener on non-existent host event `settings/updated` in `lib/index.js` (active settings updates remain reliably monitored via `settings/document-updated` and `loader/volatile-update`).
16
+ - **Client slot registration** (#59): Remove dead registration of non-existent client seat `settings.plugin.item` in `lib/client.js` (official plugin list page seat `plugins.item` and row config seat `plugins.row.config` handle settings cards).
17
+ - **Web push state path containment** (#59): Constrain custom `webPush.stateFile` paths by resolving relative paths against the DSH home directory instead of returning raw unconstrained strings.
18
+
7
19
  ## [0.4.2] - 2026-10-10
8
20
 
9
21
  ### Fixed
package/lib/client.js CHANGED
@@ -675,22 +675,17 @@ window.__ModuleLoader__.load({
675
675
  }
676
676
  }
677
677
 
678
- // In DSH 0.2.x configForms is keyed strictly by entry id (ROW_ID = 'plugin-notify').
679
- // Hold both candidates and prefer ROW_ID whenever it is ready or NS is unavailable.
680
- const [scopeRow, scopeNS] = React.useMemo(
681
- () => (ctx && ctx.configForms ? [ctx.configForms.get(ROW_ID), ctx.configForms.get(NS)] : [undefined, undefined]),
678
+ // In DSH configForms is keyed by entry id (ROW_ID = 'plugin-notify').
679
+ // Query ROW_ID directly; no entry id in the environment has the package name.
680
+ const scope = React.useMemo(
681
+ () => (ctx && ctx.configForms ? ctx.configForms.get(ROW_ID) : undefined),
682
682
  [ctx],
683
683
  )
684
- const useSnap = (scope) => React.useSyncExternalStore(
684
+ const snapshot = React.useSyncExternalStore(
685
685
  React.useMemo(() => (cb) => (scope ? scope.subscribe(cb) : () => {}), [scope]),
686
686
  React.useCallback(() => (scope ? scope.getSnapshot() : { status: 'loading' }), [scope]),
687
687
  React.useCallback(() => ({ status: 'loading' }), []),
688
688
  )
689
- const snapRow = useSnap(scopeRow)
690
- const snapNS = useSnap(scopeNS)
691
- const useRow = scopeRow && (snapRow.status === 'ready' || snapNS.status !== 'ready')
692
- const scope = useRow ? scopeRow : (scopeNS || scopeRow)
693
- const snapshot = useRow ? snapRow : (scopeNS ? snapNS : snapRow)
694
689
 
695
690
  React.useEffect(() => { ensureStyles() }, [])
696
691
 
@@ -895,19 +890,13 @@ window.__ModuleLoader__.load({
895
890
  (props) => React.createElement(NotifyCard, { ...props, ctx }),
896
891
  )
897
892
  })
898
- // Row seat and the legacy seat kept as fallbacks for older cores.
893
+ // Row seat fallback for older cores.
899
894
  ctx.slots.inject('plugins.row.config', () => {
900
895
  ctx.slots.register(
901
896
  { name: 'plugins.row.config', key: ROW_CONFIG_KEY, locale: NS, order: 40, inject: () => ({ ctx }) },
902
897
  (props) => React.createElement(NotifyCard, { ...props, ctx }),
903
898
  )
904
899
  })
905
- ctx.slots.inject('settings.plugin.item', () => {
906
- ctx.slots.register(
907
- { name: 'settings.plugin.item', key: ROW_ID, locale: NS, order: 40, inject: () => ({ ctx }) },
908
- (props) => React.createElement(NotifyCard, { ...props, ctx }),
909
- )
910
- })
911
900
  } catch (e) {
912
901
  console.warn('[dsh-plugin-notify] settings seats failed', e)
913
902
  }
@@ -915,9 +904,7 @@ window.__ModuleLoader__.load({
915
904
  let currentSettings = {}
916
905
  if (ctx.configForms) {
917
906
  try {
918
- const candidates = [ctx.configForms.get(ROW_ID), ctx.configForms.get(NS)]
919
- const ready = candidates.find((s) => s && s.getSnapshot && s.getSnapshot().status === 'ready')
920
- const scope = ready || candidates[0]
907
+ const scope = ctx.configForms.get(ROW_ID)
921
908
  if (scope && typeof scope.subscribe === 'function') {
922
909
  scope.subscribe(() => {
923
910
  const snap = scope.getSnapshot ? scope.getSnapshot() : null
package/lib/index.js CHANGED
@@ -344,10 +344,12 @@ export function generateVapidKeys() {
344
344
  }
345
345
 
346
346
  export function resolveStatePath(webPushConfig = {}) {
347
- if (webPushConfig && typeof webPushConfig.stateFile === 'string' && webPushConfig.stateFile.trim())
348
- return webPushConfig.stateFile.trim();
349
347
  const home = (process.env.DSH_HOME && process.env.DSH_HOME.trim())
350
348
  || path.join(os.homedir(), '.dsh');
349
+ if (webPushConfig && typeof webPushConfig.stateFile === 'string' && webPushConfig.stateFile.trim()) {
350
+ const custom = webPushConfig.stateFile.trim();
351
+ return path.isAbsolute(custom) ? path.normalize(custom) : path.resolve(home, custom);
352
+ }
351
353
  return path.join(home, 'plugin-notify-state.json');
352
354
  }
353
355
 
@@ -793,7 +795,6 @@ export function apply(ctx, config = {}) {
793
795
  if (typeof ctx.on === 'function') {
794
796
  ctx.on('settings/document-updated', refreshSettings);
795
797
  ctx.on('loader/volatile-update', refreshSettings);
796
- ctx.on('settings/updated', refreshSettings);
797
798
  }
798
799
  if (typeof sctx.settings?.on === 'function') {
799
800
  try { sctx.settings.on('update', refreshSettings); } catch { /* ignore */ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-plugin-notify",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "DSH plugin: audio chimes, cross-session toasts, desktop push, IM webhooks, and web push (PWA) for turn completion, errors, and approvals.",
5
5
  "license": "MIT",
6
6
  "type": "module",