@deeplake/hivemind 0.7.75 → 0.7.76

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,18 +6,18 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
9
- "version": "0.7.75"
9
+ "version": "0.7.76"
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.75",
15
+ "version": "0.7.76",
16
16
  "source": {
17
17
  "source": "git-subdir",
18
18
  "url": "https://github.com/activeloopai/hivemind.git",
19
19
  "path": "claude-code",
20
- "sha": "46a3c497a22fbd89125eb0922d1648c6fc48eeaf"
20
+ "sha": "d3dd170f102bf2543acc874d236d766542295e8e"
21
21
  },
22
22
  "homepage": "https://github.com/activeloopai/hivemind"
23
23
  }
@@ -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.75",
4
+ "version": "0.7.76",
5
5
  "author": {
6
6
  "name": "Activeloop",
7
7
  "url": "https://deeplake.ai"
@@ -112,6 +112,19 @@ function decodeJwtPayload(token) {
112
112
  return null;
113
113
  }
114
114
  }
115
+ async function apiGet(path, token, apiUrl, orgId) {
116
+ const headers = {
117
+ Authorization: `Bearer ${token}`,
118
+ "Content-Type": "application/json",
119
+ ...deeplakeClientHeader()
120
+ };
121
+ if (orgId)
122
+ headers["X-Activeloop-Org-Id"] = orgId;
123
+ const resp = await fetch(`${apiUrl}${path}`, { headers });
124
+ if (!resp.ok)
125
+ throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
126
+ return resp.json();
127
+ }
115
128
  async function apiPost(path, body, token, apiUrl, orgId) {
116
129
  const headers = {
117
130
  Authorization: `Bearer ${token}`,
@@ -125,6 +138,10 @@ async function apiPost(path, body, token, apiUrl, orgId) {
125
138
  throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
126
139
  return resp.json();
127
140
  }
141
+ async function listOrgs(token, apiUrl = DEFAULT_API_URL) {
142
+ const data = await apiGet("/organizations", token, apiUrl);
143
+ return Array.isArray(data) ? data : [];
144
+ }
128
145
  async function healDriftedOrgToken(creds, log6 = () => {
129
146
  }) {
130
147
  if (!creds.token || !creds.orgId)
@@ -143,6 +160,33 @@ async function healDriftedOrgToken(creds, log6 = () => {
143
160
  organization_id: creds.orgId
144
161
  }, creds.token, apiUrl);
145
162
  const healed = { ...creds, token: tokenData.token.token };
163
+ try {
164
+ const orgs = await listOrgs(healed.token, apiUrl);
165
+ const matchedOrg = orgs.find((o) => o.id === creds.orgId);
166
+ if (matchedOrg && matchedOrg.name !== creds.orgName) {
167
+ log6(`orgName realigned: ${creds.orgName ?? "(unset)"} -> ${matchedOrg.name}`);
168
+ healed.orgName = matchedOrg.name;
169
+ }
170
+ } catch (e) {
171
+ log6(`orgName realign skipped: ${e.message}`);
172
+ }
173
+ const currentWs = creds.workspaceId ?? "default";
174
+ if (currentWs !== "default") {
175
+ try {
176
+ const wsList = await listWorkspaces(healed.token, apiUrl, creds.orgId);
177
+ const lcWs = currentWs.toLowerCase();
178
+ const wsMatch = wsList.find((w) => w.id === currentWs || w.name && w.name.toLowerCase() === lcWs);
179
+ if (!wsMatch) {
180
+ log6(`workspace '${currentWs}' not in org ${creds.orgId} \u2014 reset to default`);
181
+ healed.workspaceId = "default";
182
+ } else if (wsMatch.id !== currentWs) {
183
+ log6(`workspace '${currentWs}' resolved to id '${wsMatch.id}'`);
184
+ healed.workspaceId = wsMatch.id;
185
+ }
186
+ } catch (e) {
187
+ log6(`workspace realign skipped: ${e.message}`);
188
+ }
189
+ }
146
190
  saveCredentials(healed);
147
191
  log6(`token re-minted for org=${creds.orgId}`);
148
192
  return healed;
@@ -151,6 +195,11 @@ async function healDriftedOrgToken(creds, log6 = () => {
151
195
  return creds;
152
196
  }
153
197
  }
198
+ async function listWorkspaces(token, apiUrl = DEFAULT_API_URL, orgId) {
199
+ const raw = await apiGet("/workspaces", token, apiUrl, orgId);
200
+ const data = raw.data ?? raw;
201
+ return Array.isArray(data) ? data : [];
202
+ }
154
203
 
155
204
  // dist/src/utils/stdin.js
156
205
  function readStdin() {
@@ -111,6 +111,19 @@ function decodeJwtPayload(token) {
111
111
  return null;
112
112
  }
113
113
  }
114
+ async function apiGet(path, token, apiUrl, orgId) {
115
+ const headers = {
116
+ Authorization: `Bearer ${token}`,
117
+ "Content-Type": "application/json",
118
+ ...deeplakeClientHeader()
119
+ };
120
+ if (orgId)
121
+ headers["X-Activeloop-Org-Id"] = orgId;
122
+ const resp = await fetch(`${apiUrl}${path}`, { headers });
123
+ if (!resp.ok)
124
+ throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
125
+ return resp.json();
126
+ }
114
127
  async function apiPost(path, body, token, apiUrl, orgId) {
115
128
  const headers = {
116
129
  Authorization: `Bearer ${token}`,
@@ -124,6 +137,10 @@ async function apiPost(path, body, token, apiUrl, orgId) {
124
137
  throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
125
138
  return resp.json();
126
139
  }
140
+ async function listOrgs(token, apiUrl = DEFAULT_API_URL) {
141
+ const data = await apiGet("/organizations", token, apiUrl);
142
+ return Array.isArray(data) ? data : [];
143
+ }
127
144
  async function healDriftedOrgToken(creds, log7 = () => {
128
145
  }) {
129
146
  if (!creds.token || !creds.orgId)
@@ -142,6 +159,33 @@ async function healDriftedOrgToken(creds, log7 = () => {
142
159
  organization_id: creds.orgId
143
160
  }, creds.token, apiUrl);
144
161
  const healed = { ...creds, token: tokenData.token.token };
162
+ try {
163
+ const orgs = await listOrgs(healed.token, apiUrl);
164
+ const matchedOrg = orgs.find((o) => o.id === creds.orgId);
165
+ if (matchedOrg && matchedOrg.name !== creds.orgName) {
166
+ log7(`orgName realigned: ${creds.orgName ?? "(unset)"} -> ${matchedOrg.name}`);
167
+ healed.orgName = matchedOrg.name;
168
+ }
169
+ } catch (e) {
170
+ log7(`orgName realign skipped: ${e.message}`);
171
+ }
172
+ const currentWs = creds.workspaceId ?? "default";
173
+ if (currentWs !== "default") {
174
+ try {
175
+ const wsList = await listWorkspaces(healed.token, apiUrl, creds.orgId);
176
+ const lcWs = currentWs.toLowerCase();
177
+ const wsMatch = wsList.find((w) => w.id === currentWs || w.name && w.name.toLowerCase() === lcWs);
178
+ if (!wsMatch) {
179
+ log7(`workspace '${currentWs}' not in org ${creds.orgId} \u2014 reset to default`);
180
+ healed.workspaceId = "default";
181
+ } else if (wsMatch.id !== currentWs) {
182
+ log7(`workspace '${currentWs}' resolved to id '${wsMatch.id}'`);
183
+ healed.workspaceId = wsMatch.id;
184
+ }
185
+ } catch (e) {
186
+ log7(`workspace realign skipped: ${e.message}`);
187
+ }
188
+ }
145
189
  saveCredentials(healed);
146
190
  log7(`token re-minted for org=${creds.orgId}`);
147
191
  return healed;
@@ -150,6 +194,11 @@ async function healDriftedOrgToken(creds, log7 = () => {
150
194
  return creds;
151
195
  }
152
196
  }
197
+ async function listWorkspaces(token, apiUrl = DEFAULT_API_URL, orgId) {
198
+ const raw = await apiGet("/workspaces", token, apiUrl, orgId);
199
+ const data = raw.data ?? raw;
200
+ return Array.isArray(data) ? data : [];
201
+ }
153
202
 
154
203
  // dist/src/config.js
155
204
  import { readFileSync as readFileSync3, existsSync } from "node:fs";
@@ -110,6 +110,19 @@ function decodeJwtPayload(token) {
110
110
  return null;
111
111
  }
112
112
  }
113
+ async function apiGet(path, token, apiUrl, orgId) {
114
+ const headers = {
115
+ Authorization: `Bearer ${token}`,
116
+ "Content-Type": "application/json",
117
+ ...deeplakeClientHeader()
118
+ };
119
+ if (orgId)
120
+ headers["X-Activeloop-Org-Id"] = orgId;
121
+ const resp = await fetch(`${apiUrl}${path}`, { headers });
122
+ if (!resp.ok)
123
+ throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
124
+ return resp.json();
125
+ }
113
126
  async function apiPost(path, body, token, apiUrl, orgId) {
114
127
  const headers = {
115
128
  Authorization: `Bearer ${token}`,
@@ -123,6 +136,10 @@ async function apiPost(path, body, token, apiUrl, orgId) {
123
136
  throw new Error(`API ${resp.status}: ${await resp.text().catch(() => "")}`);
124
137
  return resp.json();
125
138
  }
139
+ async function listOrgs(token, apiUrl = DEFAULT_API_URL) {
140
+ const data = await apiGet("/organizations", token, apiUrl);
141
+ return Array.isArray(data) ? data : [];
142
+ }
126
143
  async function healDriftedOrgToken(creds, log7 = () => {
127
144
  }) {
128
145
  if (!creds.token || !creds.orgId)
@@ -141,6 +158,33 @@ async function healDriftedOrgToken(creds, log7 = () => {
141
158
  organization_id: creds.orgId
142
159
  }, creds.token, apiUrl);
143
160
  const healed = { ...creds, token: tokenData.token.token };
161
+ try {
162
+ const orgs = await listOrgs(healed.token, apiUrl);
163
+ const matchedOrg = orgs.find((o) => o.id === creds.orgId);
164
+ if (matchedOrg && matchedOrg.name !== creds.orgName) {
165
+ log7(`orgName realigned: ${creds.orgName ?? "(unset)"} -> ${matchedOrg.name}`);
166
+ healed.orgName = matchedOrg.name;
167
+ }
168
+ } catch (e) {
169
+ log7(`orgName realign skipped: ${e.message}`);
170
+ }
171
+ const currentWs = creds.workspaceId ?? "default";
172
+ if (currentWs !== "default") {
173
+ try {
174
+ const wsList = await listWorkspaces(healed.token, apiUrl, creds.orgId);
175
+ const lcWs = currentWs.toLowerCase();
176
+ const wsMatch = wsList.find((w) => w.id === currentWs || w.name && w.name.toLowerCase() === lcWs);
177
+ if (!wsMatch) {
178
+ log7(`workspace '${currentWs}' not in org ${creds.orgId} \u2014 reset to default`);
179
+ healed.workspaceId = "default";
180
+ } else if (wsMatch.id !== currentWs) {
181
+ log7(`workspace '${currentWs}' resolved to id '${wsMatch.id}'`);
182
+ healed.workspaceId = wsMatch.id;
183
+ }
184
+ } catch (e) {
185
+ log7(`workspace realign skipped: ${e.message}`);
186
+ }
187
+ }
144
188
  saveCredentials(healed);
145
189
  log7(`token re-minted for org=${creds.orgId}`);
146
190
  return healed;
@@ -149,6 +193,11 @@ async function healDriftedOrgToken(creds, log7 = () => {
149
193
  return creds;
150
194
  }
151
195
  }
196
+ async function listWorkspaces(token, apiUrl = DEFAULT_API_URL, orgId) {
197
+ const raw = await apiGet("/workspaces", token, apiUrl, orgId);
198
+ const data = raw.data ?? raw;
199
+ return Array.isArray(data) ? data : [];
200
+ }
152
201
 
153
202
  // dist/src/config.js
154
203
  import { readFileSync as readFileSync3, existsSync } from "node:fs";
@@ -148,6 +148,33 @@ async function healDriftedOrgToken(creds, log4 = () => {
148
148
  organization_id: creds.orgId
149
149
  }, creds.token, apiUrl);
150
150
  const healed = { ...creds, token: tokenData.token.token };
151
+ try {
152
+ const orgs = await listOrgs(healed.token, apiUrl);
153
+ const matchedOrg = orgs.find((o) => o.id === creds.orgId);
154
+ if (matchedOrg && matchedOrg.name !== creds.orgName) {
155
+ log4(`orgName realigned: ${creds.orgName ?? "(unset)"} -> ${matchedOrg.name}`);
156
+ healed.orgName = matchedOrg.name;
157
+ }
158
+ } catch (e) {
159
+ log4(`orgName realign skipped: ${e.message}`);
160
+ }
161
+ const currentWs = creds.workspaceId ?? "default";
162
+ if (currentWs !== "default") {
163
+ try {
164
+ const wsList = await listWorkspaces(healed.token, apiUrl, creds.orgId);
165
+ const lcWs = currentWs.toLowerCase();
166
+ const wsMatch = wsList.find((w) => w.id === currentWs || w.name && w.name.toLowerCase() === lcWs);
167
+ if (!wsMatch) {
168
+ log4(`workspace '${currentWs}' not in org ${creds.orgId} \u2014 reset to default`);
169
+ healed.workspaceId = "default";
170
+ } else if (wsMatch.id !== currentWs) {
171
+ log4(`workspace '${currentWs}' resolved to id '${wsMatch.id}'`);
172
+ healed.workspaceId = wsMatch.id;
173
+ }
174
+ } catch (e) {
175
+ log4(`workspace realign skipped: ${e.message}`);
176
+ }
177
+ }
151
178
  saveCredentials(healed);
152
179
  log4(`token re-minted for org=${creds.orgId}`);
153
180
  return healed;
@@ -1801,7 +1828,7 @@ function extractLatestVersion(body) {
1801
1828
  return typeof v === "string" && v.length > 0 ? v : null;
1802
1829
  }
1803
1830
  function getInstalledVersion() {
1804
- return "0.7.75".length > 0 ? "0.7.75" : null;
1831
+ return "0.7.76".length > 0 ? "0.7.76" : null;
1805
1832
  }
1806
1833
  function isNewer(latest, current) {
1807
1834
  const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
@@ -54,5 +54,5 @@
54
54
  }
55
55
  }
56
56
  },
57
- "version": "0.7.75"
57
+ "version": "0.7.76"
58
58
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hivemind",
3
- "version": "0.7.75",
3
+ "version": "0.7.76",
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.75",
3
+ "version": "0.7.76",
4
4
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
5
5
  "type": "module",
6
6
  "repository": {