@deeplake/hivemind 0.7.78 → 0.7.80

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.
@@ -366,38 +366,38 @@ function readQueue() {
366
366
  return { queue: [] };
367
367
  }
368
368
  }
369
- function _isQueuePathInsideHome(path, home) {
370
- const r = resolve(path);
369
+ function _isQueuePathInsideHome(path2, home) {
370
+ const r = resolve(path2);
371
371
  const h = resolve(home);
372
372
  return r.startsWith(h + "/") || r === h;
373
373
  }
374
374
  function writeQueue(q) {
375
- const path = queuePath();
375
+ const path2 = queuePath();
376
376
  const home = resolve(homedir3());
377
- if (!_isQueuePathInsideHome(path, home)) {
378
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
377
+ if (!_isQueuePathInsideHome(path2, home)) {
378
+ throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
379
379
  }
380
380
  mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
381
- const tmp = `${path}.${process.pid}.tmp`;
381
+ const tmp = `${path2}.${process.pid}.tmp`;
382
382
  writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
383
- renameSync(tmp, path);
383
+ renameSync(tmp, path2);
384
384
  }
385
385
  async function withQueueLock(fn) {
386
- const path = lockPath();
386
+ const path2 = lockPath();
387
387
  mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
388
388
  let fd = null;
389
389
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
390
390
  try {
391
- fd = openSync(path, "wx", 384);
391
+ fd = openSync(path2, "wx", 384);
392
392
  break;
393
393
  } catch (e) {
394
394
  const code = e.code;
395
395
  if (code !== "EEXIST")
396
396
  throw e;
397
397
  try {
398
- const age = Date.now() - statSync(path).mtimeMs;
398
+ const age = Date.now() - statSync(path2).mtimeMs;
399
399
  if (age > LOCK_STALE_MS) {
400
- unlinkSync(path);
400
+ unlinkSync(path2);
401
401
  continue;
402
402
  }
403
403
  } catch {
@@ -418,7 +418,7 @@ async function withQueueLock(fn) {
418
418
  } catch {
419
419
  }
420
420
  try {
421
- unlinkSync(path);
421
+ unlinkSync(path2);
422
422
  } catch {
423
423
  }
424
424
  }
@@ -694,9 +694,9 @@ var DeeplakeApi = class {
694
694
  }
695
695
  }
696
696
  /** Update specific columns on a row by path. */
697
- async updateColumns(path, columns) {
697
+ async updateColumns(path2, columns) {
698
698
  const setClauses = Object.entries(columns).map(([col, val]) => typeof val === "number" ? `${col} = ${val}` : `${col} = '${sqlStr(String(val))}'`).join(", ");
699
- await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path)}'`);
699
+ await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path2)}'`);
700
700
  }
701
701
  // ── Convenience ─────────────────────────────────────────────────────────────
702
702
  /** Create a BM25 search index on a column. */
@@ -1402,13 +1402,13 @@ var _migrated = false;
1402
1402
  function readUserConfig() {
1403
1403
  if (_cache !== null)
1404
1404
  return _cache;
1405
- const path = _configPath();
1406
- if (!existsSync4(path)) {
1405
+ const path2 = _configPath();
1406
+ if (!existsSync4(path2)) {
1407
1407
  _cache = {};
1408
1408
  return _cache;
1409
1409
  }
1410
1410
  try {
1411
- const raw = readFileSync6(path, "utf-8");
1411
+ const raw = readFileSync6(path2, "utf-8");
1412
1412
  const parsed = JSON.parse(raw);
1413
1413
  _cache = isPlainObject(parsed) ? parsed : {};
1414
1414
  } catch {
@@ -1419,13 +1419,13 @@ function readUserConfig() {
1419
1419
  function writeUserConfig(patch) {
1420
1420
  const current = readUserConfig();
1421
1421
  const merged = deepMerge(current, patch);
1422
- const path = _configPath();
1423
- const dir = dirname(path);
1422
+ const path2 = _configPath();
1423
+ const dir = dirname(path2);
1424
1424
  if (!existsSync4(dir))
1425
1425
  mkdirSync4(dir, { recursive: true });
1426
- const tmp = `${path}.tmp.${process.pid}`;
1426
+ const tmp = `${path2}.tmp.${process.pid}`;
1427
1427
  writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1428
- renameSync2(tmp, path);
1428
+ renameSync2(tmp, path2);
1429
1429
  _cache = merged;
1430
1430
  return merged;
1431
1431
  }
@@ -1570,8 +1570,8 @@ function createSymlinkAtomic(target, link) {
1570
1570
  }
1571
1571
 
1572
1572
  // dist/src/hooks/hermes/capture.js
1573
- import { fileURLToPath as fileURLToPath3 } from "node:url";
1574
- import { dirname as dirname7, join as join20 } from "node:path";
1573
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
1574
+ import { dirname as dirname8, join as join21 } from "node:path";
1575
1575
 
1576
1576
  // dist/src/hooks/summary-state.js
1577
1577
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
@@ -1718,13 +1718,13 @@ import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
1718
1718
  import { mkdirSync as mkdirSync7, appendFileSync as appendFileSync2 } from "node:fs";
1719
1719
  import { join as join11 } from "node:path";
1720
1720
  function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1721
- const path = join11(hooksDir, filename);
1721
+ const path2 = join11(hooksDir, filename);
1722
1722
  return {
1723
- path,
1723
+ path: path2,
1724
1724
  log(msg) {
1725
1725
  try {
1726
1726
  mkdirSync7(hooksDir, { recursive: true });
1727
- appendFileSync2(path, `[${utcTimestamp()}] ${msg}
1727
+ appendFileSync2(path2, `[${utcTimestamp()}] ${msg}
1728
1728
  `);
1729
1729
  } catch {
1730
1730
  }
@@ -1777,10 +1777,10 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
1777
1777
  // dist/src/utils/spawn-detached.js
1778
1778
  import { spawn as nodeSpawn } from "node:child_process";
1779
1779
  function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
1780
- const spawn2 = deps.spawn ?? nodeSpawn;
1780
+ const spawn3 = deps.spawn ?? nodeSpawn;
1781
1781
  const execPath = deps.execPath ?? process.execPath;
1782
1782
  try {
1783
- const child = spawn2(execPath, [workerPath, ...args], {
1783
+ const child = spawn3(execPath, [workerPath, ...args], {
1784
1784
  detached: true,
1785
1785
  stdio: ["ignore", "ignore", "ignore"],
1786
1786
  // Suppress the transient console window Windows would otherwise pop for
@@ -2317,12 +2317,132 @@ function tryStopCounterTrigger(opts) {
2317
2317
  }
2318
2318
  }
2319
2319
 
2320
+ // dist/src/skillify/skillopt-trigger.js
2321
+ import { spawn as spawn2 } from "node:child_process";
2322
+ import fs from "node:fs";
2323
+ import path from "node:path";
2324
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
2325
+
2326
+ // dist/src/skillify/manifest.js
2327
+ import { existsSync as existsSync11, lstatSync as lstatSync3, mkdirSync as mkdirSync12, readFileSync as readFileSync11, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync10 } from "node:fs";
2328
+ import { dirname as dirname7, join as join20 } from "node:path";
2329
+
2330
+ // dist/src/skillify/skillopt-env.js
2331
+ var SKILLOPT_ENV = {
2332
+ /** User-set kill switch: "1" disables the whole trigger. */
2333
+ DISABLED: "HIVEMIND_SKILLOPT_DISABLED",
2334
+ /** Recursion guard the trigger sets on the spawned worker so the worker can't re-arm. */
2335
+ WORKER: "HIVEMIND_SKILLOPT_WORKER",
2336
+ /** Worker inputs, handed trigger → worker via the child env. */
2337
+ SESSION: "HIVEMIND_SKILLOPT_SESSION",
2338
+ SKILL: "HIVEMIND_SKILLOPT_SKILL",
2339
+ REACTION: "HIVEMIND_SKILLOPT_REACTION",
2340
+ TOOL_USE_ID: "HIVEMIND_SKILLOPT_TOOL_USE_ID",
2341
+ /** Which agent's CLI runs the judge/proposer (claude_code/codex/hermes/cursor/pi). */
2342
+ AGENT: "HIVEMIND_SKILLOPT_AGENT",
2343
+ /** K-message judgment-window size override. */
2344
+ JUDGE_WINDOW: "HIVEMIND_SKILLOPT_JUDGE_WINDOW"
2345
+ };
2346
+
2347
+ // dist/src/skillify/skillopt-trigger.js
2348
+ var log5 = (m) => log("skillopt-trigger", m);
2349
+ function defaultHasCreds() {
2350
+ try {
2351
+ return Boolean(loadConfig()?.token);
2352
+ } catch {
2353
+ return false;
2354
+ }
2355
+ }
2356
+ var MAX_REACTION = 8e3;
2357
+ function pendingFile(sessionId) {
2358
+ const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 200);
2359
+ return path.join(getStateDir(), "skillopt", "pending", `${safe}.json`);
2360
+ }
2361
+ var fileStore = {
2362
+ load(sessionId) {
2363
+ try {
2364
+ return JSON.parse(fs.readFileSync(pendingFile(sessionId), "utf8"));
2365
+ } catch {
2366
+ return null;
2367
+ }
2368
+ },
2369
+ save(sessionId, p) {
2370
+ try {
2371
+ const f = pendingFile(sessionId);
2372
+ if (p === null) {
2373
+ try {
2374
+ fs.unlinkSync(f);
2375
+ } catch {
2376
+ }
2377
+ return;
2378
+ }
2379
+ fs.mkdirSync(path.dirname(f), { recursive: true });
2380
+ const tmp = `${f}.${process.pid}.tmp`;
2381
+ fs.writeFileSync(tmp, JSON.stringify(p));
2382
+ fs.renameSync(tmp, f);
2383
+ } catch {
2384
+ }
2385
+ }
2386
+ };
2387
+ function runEventTrigger(sessionId, reaction, opts = {}) {
2388
+ const deps = opts.deps ?? {};
2389
+ const env = deps.env ?? process.env;
2390
+ if (env[SKILLOPT_ENV.DISABLED] === "1")
2391
+ return { fired: false, reason: "disabled" };
2392
+ if (env[SKILLOPT_ENV.WORKER] === "1")
2393
+ return { fired: false, reason: "in-worker" };
2394
+ if (!sessionId)
2395
+ return { fired: false, reason: "no-skill" };
2396
+ const store = deps.store ?? fileStore;
2397
+ const p = store.load(sessionId);
2398
+ if (!p)
2399
+ return { fired: false, reason: "no-skill" };
2400
+ if (!(deps.canFire ?? defaultHasCreds)())
2401
+ return { fired: false, reason: "no-creds" };
2402
+ store.save(sessionId, p.budget - 1 <= 0 ? null : { ...p, budget: p.budget - 1 });
2403
+ (deps.spawnWorker ?? spawnWorker)(sessionId, p.skill, reaction ?? "", p.toolUseId, opts.agent);
2404
+ return { fired: true, reason: "spawned" };
2405
+ }
2406
+ function spawnWorker(sessionId, skill, reaction, toolUseId, agent) {
2407
+ try {
2408
+ const here = path.dirname(fileURLToPath3(import.meta.url));
2409
+ const entry = path.join(here, "skillopt-worker.js");
2410
+ const child = spawn2(process.execPath, [entry], {
2411
+ detached: true,
2412
+ stdio: "ignore",
2413
+ env: {
2414
+ ...process.env,
2415
+ [SKILLOPT_ENV.WORKER]: "1",
2416
+ [SKILLOPT_ENV.SESSION]: sessionId,
2417
+ [SKILLOPT_ENV.SKILL]: skill,
2418
+ [SKILLOPT_ENV.REACTION]: (reaction ?? "").slice(0, MAX_REACTION),
2419
+ ...toolUseId ? { [SKILLOPT_ENV.TOOL_USE_ID]: toolUseId } : {},
2420
+ ...agent ? { [SKILLOPT_ENV.AGENT]: agent } : {}
2421
+ }
2422
+ });
2423
+ child.unref();
2424
+ log5(`spawned skillopt worker for ${skill} in ${sessionId}${agent ? ` (agent=${agent})` : ""}`);
2425
+ } catch (e) {
2426
+ log5(`spawn failed (swallowed): ${e?.message ?? e}`);
2427
+ }
2428
+ }
2429
+
2430
+ // dist/src/hooks/shared/skillopt-hook.js
2431
+ function reactSkillOpt(sessionId, prompt, agent) {
2432
+ try {
2433
+ if (prompt === void 0 || prompt.trim() === "" || process.env.HIVEMIND_WIKI_WORKER === "1")
2434
+ return;
2435
+ runEventTrigger(sessionId, prompt, { agent });
2436
+ } catch {
2437
+ }
2438
+ }
2439
+
2320
2440
  // dist/src/hooks/hermes/capture.js
2321
- var log5 = (msg) => log("hermes-capture", msg);
2441
+ var log6 = (msg) => log("hermes-capture", msg);
2322
2442
  function resolveEmbedDaemonPath() {
2323
- return join20(dirname7(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
2443
+ return join21(dirname8(fileURLToPath4(import.meta.url)), "embeddings", "embed-daemon.js");
2324
2444
  }
2325
- var __bundleDir = dirname7(fileURLToPath3(import.meta.url));
2445
+ var __bundleDir = dirname8(fileURLToPath4(import.meta.url));
2326
2446
  var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".claude-plugin") ?? "";
2327
2447
  if (!embeddingsDisabled()) {
2328
2448
  try {
@@ -2344,7 +2464,7 @@ async function main() {
2344
2464
  const input = await readStdin();
2345
2465
  const config = loadConfig();
2346
2466
  if (!config) {
2347
- log5("no config");
2467
+ log6("no config");
2348
2468
  return;
2349
2469
  }
2350
2470
  const sessionId = input.session_id ?? `hermes-${Date.now()}`;
@@ -2361,17 +2481,19 @@ async function main() {
2361
2481
  timestamp: ts
2362
2482
  };
2363
2483
  let entry = null;
2484
+ let reactPrompt;
2364
2485
  if (event === "pre_llm_call") {
2365
2486
  const prompt = pickString(extra.prompt, extra.user_message, extra.message?.content);
2366
2487
  if (!prompt) {
2367
- log5(`pre_llm_call: no prompt found in extra`);
2488
+ log6(`pre_llm_call: no prompt found in extra`);
2368
2489
  return;
2369
2490
  }
2370
- log5(`user session=${sessionId}`);
2491
+ log6(`user session=${sessionId}`);
2371
2492
  entry = { id: crypto.randomUUID(), ...meta, type: "user_message", content: prompt };
2493
+ reactPrompt = prompt;
2372
2494
  } else if (event === "post_tool_call" && typeof input.tool_name === "string") {
2373
2495
  const toolResponse = extra.tool_result ?? extra.tool_output ?? extra.result ?? extra.output;
2374
- log5(`tool=${input.tool_name} session=${sessionId}`);
2496
+ log6(`tool=${input.tool_name} session=${sessionId}`);
2375
2497
  entry = {
2376
2498
  id: crypto.randomUUID(),
2377
2499
  ...meta,
@@ -2383,18 +2505,18 @@ async function main() {
2383
2505
  } else if (event === "post_llm_call") {
2384
2506
  const text = pickString(extra.response, extra.assistant_message, extra.message?.content);
2385
2507
  if (!text) {
2386
- log5(`post_llm_call: no response found in extra`);
2508
+ log6(`post_llm_call: no response found in extra`);
2387
2509
  return;
2388
2510
  }
2389
- log5(`assistant session=${sessionId}`);
2511
+ log6(`assistant session=${sessionId}`);
2390
2512
  entry = { id: crypto.randomUUID(), ...meta, type: "assistant_message", content: text };
2391
2513
  } else {
2392
- log5(`unknown/unhandled event: ${event}, skipping`);
2514
+ log6(`unknown/unhandled event: ${event}, skipping`);
2393
2515
  return;
2394
2516
  }
2395
2517
  const sessionPath = buildSessionPath(config, sessionId);
2396
2518
  const line = JSON.stringify(entry);
2397
- log5(`writing to ${sessionPath}`);
2519
+ log6(`writing to ${sessionPath}`);
2398
2520
  const projectName = projectNameFromCwd(cwd);
2399
2521
  const filename = sessionPath.split("/").pop() ?? "";
2400
2522
  const jsonForSql = line.replace(/'/g, "''");
@@ -2405,14 +2527,15 @@ async function main() {
2405
2527
  await api.query(insertSql);
2406
2528
  } catch (e) {
2407
2529
  if (e.message?.includes("permission denied") || e.message?.includes("does not exist")) {
2408
- log5("table missing, creating and retrying");
2530
+ log6("table missing, creating and retrying");
2409
2531
  await api.ensureSessionsTable(sessionsTable);
2410
2532
  await api.query(insertSql);
2411
2533
  } else {
2412
2534
  throw e;
2413
2535
  }
2414
2536
  }
2415
- log5("capture ok \u2192 cloud");
2537
+ log6("capture ok \u2192 cloud");
2538
+ reactSkillOpt(sessionId, reactPrompt, "hermes");
2416
2539
  maybeTriggerPeriodicSummary(sessionId, cwd, config);
2417
2540
  if (event === "post_llm_call" && process.env.HIVEMIND_WIKI_WORKER !== "1" && process.env.HIVEMIND_SKILLIFY_WORKER !== "1") {
2418
2541
  tryStopCounterTrigger({
@@ -2433,7 +2556,7 @@ function maybeTriggerPeriodicSummary(sessionId, cwd, config) {
2433
2556
  if (!shouldTrigger(state, cfg))
2434
2557
  return;
2435
2558
  if (!tryAcquireLock(sessionId)) {
2436
- log5(`periodic trigger suppressed (lock held) session=${sessionId}`);
2559
+ log6(`periodic trigger suppressed (lock held) session=${sessionId}`);
2437
2560
  return;
2438
2561
  }
2439
2562
  wikiLog(`Periodic: threshold hit (total=${state.totalCount}, since=${state.totalCount - state.lastSummaryCount}, N=${cfg.everyNMessages}, hours=${cfg.everyHours})`);
@@ -2446,17 +2569,17 @@ function maybeTriggerPeriodicSummary(sessionId, cwd, config) {
2446
2569
  reason: "Periodic"
2447
2570
  });
2448
2571
  } catch (e) {
2449
- log5(`periodic spawn failed: ${e.message}`);
2572
+ log6(`periodic spawn failed: ${e.message}`);
2450
2573
  try {
2451
2574
  releaseLock(sessionId);
2452
2575
  } catch {
2453
2576
  }
2454
2577
  }
2455
2578
  } catch (e) {
2456
- log5(`periodic trigger error: ${e.message}`);
2579
+ log6(`periodic trigger error: ${e.message}`);
2457
2580
  }
2458
2581
  }
2459
2582
  main().catch((e) => {
2460
- log5(`fatal: ${e.message}`);
2583
+ log6(`fatal: ${e.message}`);
2461
2584
  process.exit(0);
2462
2585
  });