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