hookstack-cli 0.1.52 → 0.1.54

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.
Files changed (2) hide show
  1. package/bin/core.mjs +11 -2
  2. package/package.json +1 -1
package/bin/core.mjs CHANGED
@@ -106,14 +106,23 @@ export function assertSafeTarget(destDir, target) {
106
106
  }
107
107
 
108
108
  // Merges incoming settings.json hook fragments into existing ones, grouping by
109
- // event then by matcher (no overwrite). Same contract as src/lib/mergeConfig.
109
+ // event then by matcher (no overwrite, no duplicate commands). Same contract as
110
+ // src/lib/mergeConfig. Running install twice yields the same result as once.
110
111
  export function mergeHooks(existing, incoming) {
111
112
  const merged = structuredClone(existing)
112
113
  for (const [event, entries] of Object.entries(incoming)) {
113
114
  merged[event] ??= []
114
115
  for (const entry of entries) {
115
116
  const found = merged[event].find(e => (e.matcher ?? '') === (entry.matcher ?? ''))
116
- if (found) found.hooks.push(...entry.hooks)
117
+ if (found) {
118
+ const seen = new Set(found.hooks.map(h => h.command))
119
+ for (const h of entry.hooks) {
120
+ if (!seen.has(h.command)) {
121
+ found.hooks.push(h)
122
+ seen.add(h.command)
123
+ }
124
+ }
125
+ }
117
126
  else merged[event].push({ ...entry, hooks: [...entry.hooks] })
118
127
  }
119
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookstack-cli",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
4
4
  "description": "CLI installer for the Hookstack catalogue of Claude Code hooks",
5
5
  "type": "module",
6
6
  "bin": {