@deeplake/hivemind 0.7.76 → 0.7.78

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.
@@ -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 dirname7 } from "node:path";
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";
@@ -626,7 +626,7 @@ function getQueryTimeoutMs() {
626
626
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
627
627
  }
628
628
  function sleep2(ms) {
629
- return new Promise((resolve2) => setTimeout(resolve2, ms));
629
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
630
630
  }
631
631
  function isTimeoutError(error) {
632
632
  const name = error instanceof Error ? error.name.toLowerCase() : "";
@@ -656,7 +656,7 @@ var Semaphore = class {
656
656
  this.active++;
657
657
  return;
658
658
  }
659
- await new Promise((resolve2) => this.waiting.push(resolve2));
659
+ await new Promise((resolve3) => this.waiting.push(resolve3));
660
660
  }
661
661
  release() {
662
662
  this.active--;
@@ -1408,13 +1408,13 @@ function maybeAutoMineLocal() {
1408
1408
 
1409
1409
  // dist/src/utils/stdin.js
1410
1410
  function readStdin() {
1411
- return new Promise((resolve2, reject) => {
1411
+ return new Promise((resolve3, reject) => {
1412
1412
  let data = "";
1413
1413
  process.stdin.setEncoding("utf-8");
1414
1414
  process.stdin.on("data", (chunk) => data += chunk);
1415
1415
  process.stdin.on("end", () => {
1416
1416
  try {
1417
- resolve2(JSON.parse(data));
1417
+ resolve3(JSON.parse(data));
1418
1418
  } catch (err) {
1419
1419
  reject(new Error(`Failed to parse hook input: ${err}`));
1420
1420
  }
@@ -2255,9 +2255,213 @@ function spawnGraphPullWorker(cwd, bundleDir, deps = {}) {
2255
2255
  }
2256
2256
  }
2257
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
+
2258
2462
  // dist/src/hooks/cursor/session-start.js
2259
2463
  var log6 = (msg) => log("cursor-session-start", msg);
2260
- var __bundleDir = dirname7(fileURLToPath2(import.meta.url));
2464
+ var __bundleDir = dirname10(fileURLToPath2(import.meta.url));
2261
2465
  var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
2262
2466
 
2263
2467
  Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
@@ -2378,9 +2582,12 @@ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`
2378
2582
  const baseWithGoals = creds?.token ? `${baseContext}
2379
2583
 
2380
2584
  ${GOALS_INSTRUCTIONS_CLI}` : baseContext;
2381
- const additionalContext = rulesBlock ? `${baseWithGoals}
2585
+ const withRules = rulesBlock ? `${baseWithGoals}
2382
2586
 
2383
2587
  ${rulesBlock}` : baseWithGoals;
2588
+ const graphLine = graphContextLine(resolveCwd(input));
2589
+ const additionalContext = graphLine ? `${withRules}
2590
+ ${graphLine}` : withRules;
2384
2591
  console.log(JSON.stringify({ additional_context: additionalContext }));
2385
2592
  }
2386
2593
  main().catch((e) => {