@deeplake/hivemind 0.7.24 → 0.7.26

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.
@@ -6,13 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
9
- "version": "0.7.24"
9
+ "version": "0.7.26"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "hivemind",
14
14
  "description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
15
- "version": "0.7.24",
15
+ "version": "0.7.26",
16
16
  "source": "./claude-code",
17
17
  "homepage": "https://github.com/activeloopai/hivemind"
18
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hivemind",
3
3
  "description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
4
- "version": "0.7.24",
4
+ "version": "0.7.26",
5
5
  "author": {
6
6
  "name": "Activeloop",
7
7
  "url": "https://deeplake.ai"
package/bundle/cli.js CHANGED
@@ -181,74 +181,74 @@ function pluginAlreadyInstalled() {
181
181
  return r.stdout.includes(PLUGIN_KEY);
182
182
  }
183
183
  var PLUGIN_SCOPES = ["user", "project", "local", "managed"];
184
- function resolvePluginRoot() {
185
- return join2(homedir2(), ".claude", "plugins", "hivemind");
186
- }
187
- function marketplaceHooksJsonPath() {
188
- return join2(homedir2(), ".claude", "plugins", "marketplaces", "hivemind", "claude-code", "hooks", "hooks.json");
189
- }
190
184
  function settingsJsonPath() {
191
185
  return join2(homedir2(), ".claude", "settings.json");
192
186
  }
193
- function resolveCommand(command, pluginRoot) {
194
- return command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRoot);
195
- }
196
- function isHivemindMatcher(matcher) {
197
- return matcher.hooks?.some((h) => {
198
- if (typeof h.command !== "string")
199
- return false;
200
- const normalized = h.command.replace(/\\/g, "/");
201
- return normalized.includes("plugins/hivemind/bundle/");
202
- }) ?? false;
187
+ var LEGACY_PATH_FRAGMENT = ".claude/plugins/hivemind/bundle/";
188
+ function isBrokenHivemindHookEntry(h) {
189
+ if (typeof h.command !== "string")
190
+ return false;
191
+ const normalized = h.command.replace(/\\/g, "/");
192
+ if (!normalized.includes(LEGACY_PATH_FRAGMENT))
193
+ return false;
194
+ const match = normalized.match(/"([^"]+\.claude\/plugins\/hivemind\/bundle\/[^"]+)"/);
195
+ const filePath = match ? match[1] : null;
196
+ if (!filePath)
197
+ return false;
198
+ return !existsSync2(filePath);
203
199
  }
204
- function syncHivemindHooksToSettings() {
205
- const hooksPath = marketplaceHooksJsonPath();
200
+ function cleanupBrokenSettingsHooks() {
206
201
  const settingsPath = settingsJsonPath();
207
- if (!existsSync2(hooksPath))
208
- return { changed: false, events: [] };
209
- let canonical;
202
+ if (!existsSync2(settingsPath))
203
+ return { removed: 0, events: [] };
204
+ let parsed;
210
205
  try {
211
- canonical = JSON.parse(readFileSync2(hooksPath, "utf-8"));
206
+ parsed = JSON.parse(readFileSync2(settingsPath, "utf-8"));
212
207
  } catch {
213
- return { changed: false, events: [] };
208
+ return { removed: 0, events: [] };
209
+ }
210
+ if (!parsed || typeof parsed !== "object")
211
+ return { removed: 0, events: [] };
212
+ const settings = parsed;
213
+ if (!settings.hooks || typeof settings.hooks !== "object")
214
+ return { removed: 0, events: [] };
215
+ let removed = 0;
216
+ const touchedEvents = [];
217
+ for (const [event, matchers] of Object.entries(settings.hooks)) {
218
+ if (!Array.isArray(matchers))
219
+ continue;
220
+ const cleanedMatchers = [];
221
+ let eventTouched = false;
222
+ for (const m of matchers) {
223
+ if (!m || !Array.isArray(m.hooks)) {
224
+ cleanedMatchers.push(m);
225
+ continue;
226
+ }
227
+ const keptHooks = m.hooks.filter((h) => {
228
+ const broken = isBrokenHivemindHookEntry(h);
229
+ if (broken) {
230
+ removed += 1;
231
+ eventTouched = true;
232
+ }
233
+ return !broken;
234
+ });
235
+ if (keptHooks.length > 0) {
236
+ cleanedMatchers.push({ ...m, hooks: keptHooks });
237
+ } else if (m.hooks.length > 0) {
238
+ eventTouched = true;
239
+ } else {
240
+ cleanedMatchers.push(m);
241
+ }
242
+ }
243
+ if (eventTouched) {
244
+ settings.hooks[event] = cleanedMatchers;
245
+ touchedEvents.push(event);
246
+ }
214
247
  }
215
- if (!canonical.hooks)
216
- return { changed: false, events: [] };
217
- let settings = {};
218
- if (existsSync2(settingsPath)) {
219
- try {
220
- settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
221
- } catch {
222
- return { changed: false, events: [] };
223
- }
224
- }
225
- settings.hooks = settings.hooks ?? {};
226
- const pluginRoot = resolvePluginRoot();
227
- const changedEvents = [];
228
- let changed = false;
229
- for (const [event, matchers] of Object.entries(canonical.hooks)) {
230
- const resolvedMatchers = matchers.map((m) => ({
231
- ...m.matcher !== void 0 ? { matcher: m.matcher } : {},
232
- hooks: m.hooks.map((h) => ({
233
- ...h.type !== void 0 ? { type: h.type } : {},
234
- ...h.command !== void 0 ? { command: resolveCommand(h.command, pluginRoot) } : {},
235
- ...h.timeout !== void 0 ? { timeout: h.timeout } : {},
236
- ...h.async !== void 0 ? { async: h.async } : {}
237
- }))
238
- }));
239
- const existing = settings.hooks[event] ?? [];
240
- const preserved = existing.filter((m) => !isHivemindMatcher(m));
241
- const next = [...preserved, ...resolvedMatchers];
242
- if (JSON.stringify(next) !== JSON.stringify(existing)) {
243
- settings.hooks[event] = next;
244
- changedEvents.push(event);
245
- changed = true;
246
- }
247
- }
248
- if (changed) {
248
+ if (removed > 0) {
249
249
  writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
250
250
  }
251
- return { changed, events: changedEvents };
251
+ return { removed, events: touchedEvents };
252
252
  }
253
253
  function installClaude() {
254
254
  requireClaudeCli();
@@ -273,12 +273,12 @@ function installClaude() {
273
273
  }
274
274
  runClaude(["plugin", "enable", PLUGIN_KEY]);
275
275
  try {
276
- const sync = syncHivemindHooksToSettings();
277
- if (sync.changed) {
278
- log(` Claude Code settings.json hooks synced (${sync.events.join(", ")})`);
276
+ const cleanup = cleanupBrokenSettingsHooks();
277
+ if (cleanup.removed > 0) {
278
+ log(` Claude Code settings.json cleaned: removed ${cleanup.removed} stale hook entr${cleanup.removed === 1 ? "y" : "ies"} (events: ${cleanup.events.join(", ")})`);
279
279
  }
280
280
  } catch (e) {
281
- log(` Claude Code settings.json sync skipped: ${e?.message ?? String(e)}`);
281
+ log(` Claude Code settings.json cleanup skipped: ${e?.message ?? String(e)}`);
282
282
  }
283
283
  }
284
284
  function uninstallClaude() {
@@ -1073,7 +1073,7 @@ function extractLatestVersion(body) {
1073
1073
  return typeof v === "string" && v.length > 0 ? v : null;
1074
1074
  }
1075
1075
  function getInstalledVersion() {
1076
- return "0.7.24".length > 0 ? "0.7.24" : null;
1076
+ return "0.7.26".length > 0 ? "0.7.26" : null;
1077
1077
  }
1078
1078
  function isNewer(latest, current) {
1079
1079
  const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
@@ -52,5 +52,5 @@
52
52
  }
53
53
  }
54
54
  },
55
- "version": "0.7.24"
55
+ "version": "0.7.26"
56
56
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hivemind",
3
- "version": "0.7.24",
3
+ "version": "0.7.26",
4
4
  "type": "module",
5
5
  "description": "Hivemind — cloud-backed persistent shared memory for AI agents, powered by DeepLake",
6
6
  "license": "Apache-2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeplake/hivemind",
3
- "version": "0.7.24",
3
+ "version": "0.7.26",
4
4
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
5
5
  "type": "module",
6
6
  "repository": {