@deeplake/hivemind 0.7.75 → 0.7.77
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +1077 -230
- package/codex/bundle/graph-on-stop.js +3148 -0
- package/codex/bundle/graph-pull-worker.js +40 -1
- package/codex/bundle/pre-tool-use.js +1237 -21
- package/codex/bundle/session-start.js +49 -0
- package/codex/bundle/shell/deeplake-shell.js +725 -20
- package/codex/skills/hivemind-graph/SKILL.md +94 -0
- package/cursor/bundle/graph-on-stop.js +3148 -0
- package/cursor/bundle/graph-pull-worker.js +40 -1
- package/cursor/bundle/pre-tool-use.js +1232 -8
- package/cursor/bundle/session-start.js +263 -7
- package/cursor/bundle/shell/deeplake-shell.js +725 -20
- package/hermes/bundle/graph-on-stop.js +3148 -0
- package/hermes/bundle/graph-pull-worker.js +40 -1
- package/hermes/bundle/pre-tool-use.js +1225 -8
- package/hermes/bundle/session-start.js +262 -8
- package/hermes/bundle/shell/deeplake-shell.js +725 -20
- package/openclaw/dist/index.js +28 -1
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +2 -1
- package/scripts/ensure-tree-sitter.mjs +6 -1
|
@@ -53,7 +53,7 @@ var init_index_marker_store = __esm({
|
|
|
53
53
|
|
|
54
54
|
// dist/src/hooks/hermes/session-start.js
|
|
55
55
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
56
|
-
import { dirname as
|
|
56
|
+
import { dirname as dirname10 } from "node:path";
|
|
57
57
|
|
|
58
58
|
// dist/src/commands/auth.js
|
|
59
59
|
import { execSync } from "node:child_process";
|
|
@@ -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";
|
|
@@ -576,7 +625,7 @@ function getQueryTimeoutMs() {
|
|
|
576
625
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
577
626
|
}
|
|
578
627
|
function sleep2(ms) {
|
|
579
|
-
return new Promise((
|
|
628
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
580
629
|
}
|
|
581
630
|
function isTimeoutError(error) {
|
|
582
631
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -606,7 +655,7 @@ var Semaphore = class {
|
|
|
606
655
|
this.active++;
|
|
607
656
|
return;
|
|
608
657
|
}
|
|
609
|
-
await new Promise((
|
|
658
|
+
await new Promise((resolve3) => this.waiting.push(resolve3));
|
|
610
659
|
}
|
|
611
660
|
release() {
|
|
612
661
|
this.active--;
|
|
@@ -1358,13 +1407,13 @@ function maybeAutoMineLocal() {
|
|
|
1358
1407
|
|
|
1359
1408
|
// dist/src/utils/stdin.js
|
|
1360
1409
|
function readStdin() {
|
|
1361
|
-
return new Promise((
|
|
1410
|
+
return new Promise((resolve3, reject) => {
|
|
1362
1411
|
let data = "";
|
|
1363
1412
|
process.stdin.setEncoding("utf-8");
|
|
1364
1413
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
1365
1414
|
process.stdin.on("end", () => {
|
|
1366
1415
|
try {
|
|
1367
|
-
|
|
1416
|
+
resolve3(JSON.parse(data));
|
|
1368
1417
|
} catch (err) {
|
|
1369
1418
|
reject(new Error(`Failed to parse hook input: ${err}`));
|
|
1370
1419
|
}
|
|
@@ -2205,9 +2254,213 @@ function spawnGraphPullWorker(cwd, bundleDir, deps = {}) {
|
|
|
2205
2254
|
}
|
|
2206
2255
|
}
|
|
2207
2256
|
|
|
2257
|
+
// dist/src/graph/session-context.js
|
|
2258
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
2259
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
2260
|
+
import { join as join21 } from "node:path";
|
|
2261
|
+
|
|
2262
|
+
// dist/src/graph/last-build.js
|
|
2263
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync10, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync9 } from "node:fs";
|
|
2264
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
2265
|
+
function lastBuildPath(baseDir, worktreeId) {
|
|
2266
|
+
if (worktreeId !== void 0) {
|
|
2267
|
+
return join18(baseDir, "worktrees", worktreeId, ".last-build.json");
|
|
2268
|
+
}
|
|
2269
|
+
return join18(baseDir, ".last-build.json");
|
|
2270
|
+
}
|
|
2271
|
+
function readLastBuild(baseDir, worktreeId) {
|
|
2272
|
+
let path = lastBuildPath(baseDir, worktreeId);
|
|
2273
|
+
if (!existsSync11(path)) {
|
|
2274
|
+
if (worktreeId === void 0)
|
|
2275
|
+
return null;
|
|
2276
|
+
const legacy = lastBuildPath(baseDir, void 0);
|
|
2277
|
+
if (!existsSync11(legacy))
|
|
2278
|
+
return null;
|
|
2279
|
+
path = legacy;
|
|
2280
|
+
}
|
|
2281
|
+
let raw;
|
|
2282
|
+
try {
|
|
2283
|
+
raw = readFileSync11(path, "utf8");
|
|
2284
|
+
} catch {
|
|
2285
|
+
return null;
|
|
2286
|
+
}
|
|
2287
|
+
let parsed;
|
|
2288
|
+
try {
|
|
2289
|
+
parsed = JSON.parse(raw);
|
|
2290
|
+
} catch {
|
|
2291
|
+
return null;
|
|
2292
|
+
}
|
|
2293
|
+
if (parsed === null || typeof parsed !== "object")
|
|
2294
|
+
return null;
|
|
2295
|
+
const o = parsed;
|
|
2296
|
+
if (typeof o.ts !== "number" || !Number.isFinite(o.ts))
|
|
2297
|
+
return null;
|
|
2298
|
+
if (o.commit_sha !== null && typeof o.commit_sha !== "string")
|
|
2299
|
+
return null;
|
|
2300
|
+
if (typeof o.snapshot_sha256 !== "string")
|
|
2301
|
+
return null;
|
|
2302
|
+
const out = { ts: o.ts, commit_sha: o.commit_sha, snapshot_sha256: o.snapshot_sha256 };
|
|
2303
|
+
if (typeof o.node_count === "number" && Number.isFinite(o.node_count) && o.node_count >= 0) {
|
|
2304
|
+
out.node_count = o.node_count;
|
|
2305
|
+
}
|
|
2306
|
+
if (typeof o.edge_count === "number" && Number.isFinite(o.edge_count) && o.edge_count >= 0) {
|
|
2307
|
+
out.edge_count = o.edge_count;
|
|
2308
|
+
}
|
|
2309
|
+
return out;
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
// dist/src/graph/snapshot.js
|
|
2313
|
+
import { createHash } from "node:crypto";
|
|
2314
|
+
import { mkdirSync as mkdirSync12, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "node:fs";
|
|
2315
|
+
import { homedir as homedir12 } from "node:os";
|
|
2316
|
+
import { dirname as dirname9, join as join20 } from "node:path";
|
|
2317
|
+
|
|
2318
|
+
// dist/src/graph/history.js
|
|
2319
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync12 } from "node:fs";
|
|
2320
|
+
import { dirname as dirname8, join as join19 } from "node:path";
|
|
2321
|
+
|
|
2322
|
+
// dist/src/graph/resolve/cross-file.js
|
|
2323
|
+
import { posix } from "node:path";
|
|
2324
|
+
|
|
2325
|
+
// dist/src/graph/snapshot.js
|
|
2326
|
+
function graphsRoot() {
|
|
2327
|
+
return process.env.HIVEMIND_GRAPHS_HOME ?? join20(homedir12(), ".hivemind", "graphs");
|
|
2328
|
+
}
|
|
2329
|
+
function repoDir(repoKey) {
|
|
2330
|
+
return join20(graphsRoot(), repoKey);
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
// dist/src/utils/repo-identity.js
|
|
2334
|
+
import { execSync as execSync2 } from "node:child_process";
|
|
2335
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
2336
|
+
import { basename as basename2, resolve as resolve2 } from "node:path";
|
|
2337
|
+
var DEFAULT_PORTS = {
|
|
2338
|
+
http: "80",
|
|
2339
|
+
https: "443",
|
|
2340
|
+
ssh: "22",
|
|
2341
|
+
git: "9418"
|
|
2342
|
+
};
|
|
2343
|
+
function normalizeGitRemoteUrl(url) {
|
|
2344
|
+
let s = url.trim();
|
|
2345
|
+
const schemeMatch = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
|
|
2346
|
+
const scheme = schemeMatch ? schemeMatch[1].toLowerCase() : null;
|
|
2347
|
+
if (schemeMatch)
|
|
2348
|
+
s = s.slice(schemeMatch[0].length);
|
|
2349
|
+
if (!scheme) {
|
|
2350
|
+
const scp = s.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/);
|
|
2351
|
+
if (scp)
|
|
2352
|
+
s = `${scp[1]}/${scp[2]}`;
|
|
2353
|
+
}
|
|
2354
|
+
s = s.replace(/^[^@/]+@/, "");
|
|
2355
|
+
if (scheme && DEFAULT_PORTS[scheme]) {
|
|
2356
|
+
s = s.replace(new RegExp(`^([^/]+):${DEFAULT_PORTS[scheme]}(/|$)`), "$1$2");
|
|
2357
|
+
}
|
|
2358
|
+
s = s.replace(/\.git\/?$/i, "");
|
|
2359
|
+
s = s.replace(/\/+$/, "");
|
|
2360
|
+
return s.toLowerCase();
|
|
2361
|
+
}
|
|
2362
|
+
function deriveProjectKey(cwd) {
|
|
2363
|
+
const absCwd = resolve2(cwd);
|
|
2364
|
+
const project = basename2(absCwd) || "unknown";
|
|
2365
|
+
let signature = null;
|
|
2366
|
+
try {
|
|
2367
|
+
const raw = execSync2("git config --get remote.origin.url", {
|
|
2368
|
+
cwd: absCwd,
|
|
2369
|
+
encoding: "utf-8",
|
|
2370
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2371
|
+
}).trim();
|
|
2372
|
+
signature = raw ? normalizeGitRemoteUrl(raw) : null;
|
|
2373
|
+
} catch {
|
|
2374
|
+
}
|
|
2375
|
+
const input = signature ?? absCwd;
|
|
2376
|
+
const key = createHash2("sha1").update(input).digest("hex").slice(0, 16);
|
|
2377
|
+
return { key, project };
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
// dist/src/graph/session-context.js
|
|
2381
|
+
function workTreeIdFor(cwd) {
|
|
2382
|
+
return createHash3("sha256").update(cwd).digest("hex").slice(0, 16);
|
|
2383
|
+
}
|
|
2384
|
+
function graphContextLine(cwd, deps = {}) {
|
|
2385
|
+
let key;
|
|
2386
|
+
let snapshotsDir;
|
|
2387
|
+
let baseDir;
|
|
2388
|
+
try {
|
|
2389
|
+
key = deriveProjectKey(cwd).key;
|
|
2390
|
+
baseDir = repoDir(key);
|
|
2391
|
+
snapshotsDir = join21(baseDir, "snapshots");
|
|
2392
|
+
} catch {
|
|
2393
|
+
return null;
|
|
2394
|
+
}
|
|
2395
|
+
if (!existsSync13(snapshotsDir))
|
|
2396
|
+
return null;
|
|
2397
|
+
const last = readLastBuild(baseDir, workTreeIdFor(cwd));
|
|
2398
|
+
if (last === null)
|
|
2399
|
+
return null;
|
|
2400
|
+
if (last.commit_sha !== null && !/^[0-9a-f]{4,64}$/.test(last.commit_sha))
|
|
2401
|
+
return null;
|
|
2402
|
+
if (!/^[0-9a-f]{64}$/.test(last.snapshot_sha256))
|
|
2403
|
+
return null;
|
|
2404
|
+
const now = (deps.now ?? Date.now)();
|
|
2405
|
+
const ageMs = Math.max(0, now - last.ts);
|
|
2406
|
+
const nodesStr = last.node_count !== void 0 ? String(last.node_count) : "?";
|
|
2407
|
+
const edgesStr = last.edge_count !== void 0 ? String(last.edge_count) : "?";
|
|
2408
|
+
const commitStr = last.commit_sha !== null ? last.commit_sha.slice(0, 7) : "no-commit";
|
|
2409
|
+
const ageStr = formatAge(ageMs);
|
|
2410
|
+
const snapshotFile = last.commit_sha ?? last.snapshot_sha256;
|
|
2411
|
+
const snapshotPath = join21(snapshotsDir, `${snapshotFile}.json`);
|
|
2412
|
+
const STALE_WARN_MS = 60 * 60 * 1e3;
|
|
2413
|
+
const STALE_HARD_MS = 24 * 60 * 60 * 1e3;
|
|
2414
|
+
let staleness;
|
|
2415
|
+
if (ageMs >= STALE_HARD_MS) {
|
|
2416
|
+
staleness = " \u26A0\uFE0F STALE: this snapshot is over a day old; the auto-rebuild may have stopped.\n Prefer reading current source for any file you suspect has changed.";
|
|
2417
|
+
} else if (ageMs >= STALE_WARN_MS) {
|
|
2418
|
+
staleness = " \u26A0\uFE0F Possibly out of date (> 1h since last build). For any file you've edited\n in this session, fall back to reading the live source instead of the graph.";
|
|
2419
|
+
} else {
|
|
2420
|
+
staleness = " Freshness: auto-rebuilds run on Stop/SessionEnd; if a file's mtime is newer\n than the build timestamp above, prefer reading the live source for that file.";
|
|
2421
|
+
}
|
|
2422
|
+
return [
|
|
2423
|
+
"",
|
|
2424
|
+
"LOCAL CODE GRAPH (TypeScript / JavaScript / Python, AST-based):",
|
|
2425
|
+
` ${nodesStr} nodes, ${edgesStr} edges (commit ${commitStr}, built ${ageStr} ago)`,
|
|
2426
|
+
"",
|
|
2427
|
+
" Use it as a fast INDEX to locate the few files/symbols that matter, then",
|
|
2428
|
+
" open them with Read to answer. It is NOT a substitute for the source: it",
|
|
2429
|
+
" omits instance-method calls (obj.method()), nested/inner functions, and",
|
|
2430
|
+
" dynamic dispatch \u2014 so confirm every claim against the file before stating it.",
|
|
2431
|
+
"",
|
|
2432
|
+
" Query via the Deeplake mount (intercepted \u2014 use `cat`, not `ls`):",
|
|
2433
|
+
" cat ~/.deeplake/memory/graph/query/<pattern> \u2190 start here",
|
|
2434
|
+
" search + 1-hop expand (callers, callees, imports). AND: query/<a>+<b>.",
|
|
2435
|
+
" cat ~/.deeplake/memory/graph/find/<pattern> substring search \u2192 handles",
|
|
2436
|
+
" cat ~/.deeplake/memory/graph/show/<handle-or-pattern> node + 1-hop neighbors",
|
|
2437
|
+
" cat ~/.deeplake/memory/graph/neighborhood/<file> symbols + cross-file links",
|
|
2438
|
+
" Also: index.md \xB7 layers \xB7 tour \xB7 path/<from>/<to>",
|
|
2439
|
+
"",
|
|
2440
|
+
" Then READ the files the graph points you to \u2014 don't answer from the graph",
|
|
2441
|
+
" alone. Cross-file calls/imports resolved for named imports across TS/JS/Python;",
|
|
2442
|
+
" bare (npm)/aliased/barrel/dynamic + instance-method dispatch stay unresolved.",
|
|
2443
|
+
` Raw snapshot (fallback): ${snapshotPath}`,
|
|
2444
|
+
staleness
|
|
2445
|
+
].join("\n");
|
|
2446
|
+
}
|
|
2447
|
+
function formatAge(ms) {
|
|
2448
|
+
const s = Math.floor(ms / 1e3);
|
|
2449
|
+
if (s < 60)
|
|
2450
|
+
return `${s}s`;
|
|
2451
|
+
const m = Math.floor(s / 60);
|
|
2452
|
+
if (m < 60)
|
|
2453
|
+
return `${m}m`;
|
|
2454
|
+
const h = Math.floor(m / 60);
|
|
2455
|
+
if (h < 24)
|
|
2456
|
+
return `${h}h`;
|
|
2457
|
+
const d = Math.floor(h / 24);
|
|
2458
|
+
return `${d}d`;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2208
2461
|
// dist/src/hooks/hermes/session-start.js
|
|
2209
2462
|
var log6 = (msg) => log("hermes-session-start", msg);
|
|
2210
|
-
var __bundleDir =
|
|
2463
|
+
var __bundleDir = dirname10(fileURLToPath2(import.meta.url));
|
|
2211
2464
|
var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
|
|
2212
2465
|
|
|
2213
2466
|
Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
|
|
@@ -2314,9 +2567,10 @@ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`
|
|
|
2314
2567
|
const baseWithGoals = creds?.token ? `${baseContext}
|
|
2315
2568
|
|
|
2316
2569
|
${GOALS_INSTRUCTIONS_CLI}` : baseContext;
|
|
2317
|
-
const
|
|
2570
|
+
const graphNote = graphContextLine(cwd) ?? "";
|
|
2571
|
+
const additional = (rulesBlock ? `${baseWithGoals}
|
|
2318
2572
|
|
|
2319
|
-
${rulesBlock}` : baseWithGoals;
|
|
2573
|
+
${rulesBlock}` : baseWithGoals) + graphNote;
|
|
2320
2574
|
console.log(JSON.stringify({ context: additional }));
|
|
2321
2575
|
}
|
|
2322
2576
|
main().catch((e) => {
|