@deeplake/hivemind 0.7.65 → 0.7.67
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 +23 -40
- package/codex/bundle/capture.js +37 -44
- package/codex/bundle/commands/auth-login.js +5 -35
- package/codex/bundle/graph-pull-worker.js +5 -35
- package/codex/bundle/pre-tool-use.js +5 -35
- package/codex/bundle/session-start-setup.js +12 -36
- package/codex/bundle/session-start.js +5 -35
- package/codex/bundle/shell/deeplake-shell.js +5 -35
- package/codex/bundle/stop.js +40 -51
- package/cursor/bundle/capture.js +40 -51
- package/cursor/bundle/commands/auth-login.js +5 -35
- package/cursor/bundle/graph-pull-worker.js +5 -35
- package/cursor/bundle/pre-tool-use.js +5 -35
- package/cursor/bundle/session-end.js +32 -13
- package/cursor/bundle/session-start.js +12 -36
- package/cursor/bundle/shell/deeplake-shell.js +5 -35
- package/hermes/bundle/capture.js +40 -51
- package/hermes/bundle/commands/auth-login.js +5 -35
- package/hermes/bundle/graph-pull-worker.js +5 -35
- package/hermes/bundle/pre-tool-use.js +5 -35
- package/hermes/bundle/session-end.js +32 -13
- package/hermes/bundle/session-start.js +12 -36
- package/hermes/bundle/shell/deeplake-shell.js +5 -35
- package/mcp/bundle/server.js +5 -35
- package/openclaw/dist/index.js +6 -30
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -477,9 +477,6 @@ function traceSql(msg) {
|
|
|
477
477
|
log3(msg);
|
|
478
478
|
}
|
|
479
479
|
var _signalledBalanceExhausted = false;
|
|
480
|
-
var _signalledLowBalance = false;
|
|
481
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
482
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
483
480
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
484
481
|
if (status !== 402)
|
|
485
482
|
return;
|
|
@@ -495,40 +492,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
495
492
|
transient: true,
|
|
496
493
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
497
494
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
498
|
-
dedupKey: { reason: "balance-zero" }
|
|
495
|
+
dedupKey: { reason: "balance-zero" },
|
|
496
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
497
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
498
|
+
// is a prompt-injection pattern external agents flag.
|
|
499
|
+
userVisibleOnly: true
|
|
499
500
|
}).catch((e) => {
|
|
500
501
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
501
502
|
});
|
|
502
503
|
}
|
|
503
|
-
function signalLowBalanceFromHeader(resp) {
|
|
504
|
-
if (_signalledLowBalance)
|
|
505
|
-
return;
|
|
506
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
507
|
-
if (!raw)
|
|
508
|
-
return;
|
|
509
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
510
|
-
return;
|
|
511
|
-
const balance = Number(raw.trim());
|
|
512
|
-
if (!Number.isFinite(balance))
|
|
513
|
-
return;
|
|
514
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
515
|
-
return;
|
|
516
|
-
if (balance <= 0)
|
|
517
|
-
return;
|
|
518
|
-
_signalledLowBalance = true;
|
|
519
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
520
|
-
enqueueNotification({
|
|
521
|
-
id: "low-balance-warning",
|
|
522
|
-
severity: "warn",
|
|
523
|
-
transient: true,
|
|
524
|
-
title: "Your org's Hivemind balance is running low",
|
|
525
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
526
|
-
dedupKey: { reason: "low-balance" }
|
|
527
|
-
}).catch((e) => {
|
|
528
|
-
_signalledLowBalance = false;
|
|
529
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
504
|
function billingUrl() {
|
|
533
505
|
try {
|
|
534
506
|
const c = loadCredentials();
|
|
@@ -654,7 +626,6 @@ var DeeplakeApi = class {
|
|
|
654
626
|
}
|
|
655
627
|
throw lastError;
|
|
656
628
|
}
|
|
657
|
-
signalLowBalanceFromHeader(resp);
|
|
658
629
|
if (resp.ok) {
|
|
659
630
|
const raw = await resp.json();
|
|
660
631
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -815,7 +786,6 @@ var DeeplakeApi = class {
|
|
|
815
786
|
...deeplakeClientHeader()
|
|
816
787
|
}
|
|
817
788
|
});
|
|
818
|
-
signalLowBalanceFromHeader(resp);
|
|
819
789
|
if (resp.ok) {
|
|
820
790
|
const data = await resp.json();
|
|
821
791
|
return {
|
|
@@ -126,7 +126,7 @@ function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// dist/src/hooks/cursor/spawn-wiki-worker.js
|
|
129
|
-
import {
|
|
129
|
+
import { execSync } from "node:child_process";
|
|
130
130
|
import { fileURLToPath } from "node:url";
|
|
131
131
|
import { dirname as dirname2, join as join6 } from "node:path";
|
|
132
132
|
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
|
|
@@ -192,6 +192,32 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
192
192
|
return null;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
// dist/src/utils/spawn-detached.js
|
|
196
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
197
|
+
function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
|
|
198
|
+
const spawn = deps.spawn ?? nodeSpawn;
|
|
199
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
200
|
+
try {
|
|
201
|
+
const child = spawn(execPath, [workerPath, ...args], {
|
|
202
|
+
detached: true,
|
|
203
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
204
|
+
// Suppress the transient console window Windows would otherwise pop for
|
|
205
|
+
// the detached worker. No-op on POSIX.
|
|
206
|
+
windowsHide: true
|
|
207
|
+
});
|
|
208
|
+
child.on("error", () => {
|
|
209
|
+
});
|
|
210
|
+
child.unref();
|
|
211
|
+
} catch {
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// dist/src/utils/project-name.js
|
|
216
|
+
import { basename } from "node:path";
|
|
217
|
+
function projectNameFromCwd(cwd) {
|
|
218
|
+
return basename(cwd ?? "") || "unknown";
|
|
219
|
+
}
|
|
220
|
+
|
|
195
221
|
// dist/src/hooks/cursor/spawn-wiki-worker.js
|
|
196
222
|
var HOME = homedir4();
|
|
197
223
|
var wikiLogger = makeWikiLogger(join6(HOME, ".cursor", "hooks"));
|
|
@@ -255,7 +281,7 @@ function findCursorBin() {
|
|
|
255
281
|
}
|
|
256
282
|
function spawnCursorWikiWorker(opts) {
|
|
257
283
|
const { config, sessionId, cwd, bundleDir, reason } = opts;
|
|
258
|
-
const projectName = cwd
|
|
284
|
+
const projectName = projectNameFromCwd(cwd);
|
|
259
285
|
const tmpDir = join6(tmpdir(), `deeplake-wiki-${sessionId}-${Date.now()}`);
|
|
260
286
|
mkdirSync3(tmpDir, { recursive: true });
|
|
261
287
|
const pluginVersion = getInstalledVersion(bundleDir, ".claude-plugin") ?? "";
|
|
@@ -280,10 +306,7 @@ function spawnCursorWikiWorker(opts) {
|
|
|
280
306
|
}));
|
|
281
307
|
wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
|
|
282
308
|
const workerPath = join6(bundleDir, "wiki-worker.js");
|
|
283
|
-
|
|
284
|
-
detached: true,
|
|
285
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
286
|
-
}).unref();
|
|
309
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
287
310
|
wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
|
|
288
311
|
}
|
|
289
312
|
function bundleDirFromImportMeta(importMetaUrl) {
|
|
@@ -291,7 +314,6 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
291
314
|
}
|
|
292
315
|
|
|
293
316
|
// dist/src/skillify/spawn-skillify-worker.js
|
|
294
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
295
317
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
296
318
|
import { dirname as dirname3, join as join8 } from "node:path";
|
|
297
319
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
@@ -412,10 +434,7 @@ function spawnSkillifyWorker(opts) {
|
|
|
412
434
|
}
|
|
413
435
|
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
414
436
|
const workerPath = join8(bundleDir, "skillify-worker.js");
|
|
415
|
-
|
|
416
|
-
detached: true,
|
|
417
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
418
|
-
}).unref();
|
|
437
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
419
438
|
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
420
439
|
}
|
|
421
440
|
|
|
@@ -426,7 +445,7 @@ import { join as join11 } from "node:path";
|
|
|
426
445
|
// dist/src/utils/repo-identity.js
|
|
427
446
|
import { execSync as execSync2 } from "node:child_process";
|
|
428
447
|
import { createHash } from "node:crypto";
|
|
429
|
-
import { basename, resolve } from "node:path";
|
|
448
|
+
import { basename as basename2, resolve } from "node:path";
|
|
430
449
|
var DEFAULT_PORTS = {
|
|
431
450
|
http: "80",
|
|
432
451
|
https: "443",
|
|
@@ -454,7 +473,7 @@ function normalizeGitRemoteUrl(url) {
|
|
|
454
473
|
}
|
|
455
474
|
function deriveProjectKey(cwd) {
|
|
456
475
|
const absCwd = resolve(cwd);
|
|
457
|
-
const project =
|
|
476
|
+
const project = basename2(absCwd) || "unknown";
|
|
458
477
|
let signature = null;
|
|
459
478
|
try {
|
|
460
479
|
const raw = execSync2("git config --get remote.origin.url", {
|
|
@@ -533,9 +533,6 @@ function traceSql(msg) {
|
|
|
533
533
|
log3(msg);
|
|
534
534
|
}
|
|
535
535
|
var _signalledBalanceExhausted = false;
|
|
536
|
-
var _signalledLowBalance = false;
|
|
537
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
538
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
539
536
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
540
537
|
if (status !== 402)
|
|
541
538
|
return;
|
|
@@ -551,40 +548,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
551
548
|
transient: true,
|
|
552
549
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
553
550
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
554
|
-
dedupKey: { reason: "balance-zero" }
|
|
551
|
+
dedupKey: { reason: "balance-zero" },
|
|
552
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
553
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
554
|
+
// is a prompt-injection pattern external agents flag.
|
|
555
|
+
userVisibleOnly: true
|
|
555
556
|
}).catch((e) => {
|
|
556
557
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
557
558
|
});
|
|
558
559
|
}
|
|
559
|
-
function signalLowBalanceFromHeader(resp) {
|
|
560
|
-
if (_signalledLowBalance)
|
|
561
|
-
return;
|
|
562
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
563
|
-
if (!raw)
|
|
564
|
-
return;
|
|
565
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
566
|
-
return;
|
|
567
|
-
const balance = Number(raw.trim());
|
|
568
|
-
if (!Number.isFinite(balance))
|
|
569
|
-
return;
|
|
570
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
571
|
-
return;
|
|
572
|
-
if (balance <= 0)
|
|
573
|
-
return;
|
|
574
|
-
_signalledLowBalance = true;
|
|
575
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
576
|
-
enqueueNotification({
|
|
577
|
-
id: "low-balance-warning",
|
|
578
|
-
severity: "warn",
|
|
579
|
-
transient: true,
|
|
580
|
-
title: "Your org's Hivemind balance is running low",
|
|
581
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
582
|
-
dedupKey: { reason: "low-balance" }
|
|
583
|
-
}).catch((e) => {
|
|
584
|
-
_signalledLowBalance = false;
|
|
585
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
560
|
function billingUrl() {
|
|
589
561
|
try {
|
|
590
562
|
const c = loadCredentials();
|
|
@@ -710,7 +682,6 @@ var DeeplakeApi = class {
|
|
|
710
682
|
}
|
|
711
683
|
throw lastError;
|
|
712
684
|
}
|
|
713
|
-
signalLowBalanceFromHeader(resp);
|
|
714
685
|
if (resp.ok) {
|
|
715
686
|
const raw = await resp.json();
|
|
716
687
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -871,7 +842,6 @@ var DeeplakeApi = class {
|
|
|
871
842
|
...deeplakeClientHeader()
|
|
872
843
|
}
|
|
873
844
|
});
|
|
874
|
-
signalLowBalanceFromHeader(resp);
|
|
875
845
|
if (resp.ok) {
|
|
876
846
|
const data = await resp.json();
|
|
877
847
|
return {
|
|
@@ -1222,6 +1192,12 @@ function sanitizeForInject(text) {
|
|
|
1222
1192
|
}
|
|
1223
1193
|
var LINE_TERMINATOR_RE = /\r\n?|[\n\u2028\u2029\u0085]/g;
|
|
1224
1194
|
|
|
1195
|
+
// dist/src/utils/project-name.js
|
|
1196
|
+
import { basename } from "node:path";
|
|
1197
|
+
function projectNameFromCwd(cwd) {
|
|
1198
|
+
return basename(cwd ?? "") || "unknown";
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1225
1201
|
// dist/src/cli/skillify-spec.js
|
|
1226
1202
|
var SKILLIFY_COMMANDS = [
|
|
1227
1203
|
{ cmd: "hivemind skillify", desc: "show scope, team, install, per-project state" },
|
|
@@ -2274,7 +2250,7 @@ async function createPlaceholder(api, table, sessionId, cwd, userName, orgName,
|
|
|
2274
2250
|
if (existing.length > 0)
|
|
2275
2251
|
return;
|
|
2276
2252
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2277
|
-
const projectName = cwd
|
|
2253
|
+
const projectName = projectNameFromCwd(cwd);
|
|
2278
2254
|
const sessionSource = `/sessions/${userName}/${userName}_${orgName}_${workspaceId}_${sessionId}.jsonl`;
|
|
2279
2255
|
const content = [
|
|
2280
2256
|
`# Session ${sessionId}`,
|
|
@@ -67172,9 +67172,6 @@ function traceSql(msg) {
|
|
|
67172
67172
|
log3(msg);
|
|
67173
67173
|
}
|
|
67174
67174
|
var _signalledBalanceExhausted = false;
|
|
67175
|
-
var _signalledLowBalance = false;
|
|
67176
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
67177
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
67178
67175
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
67179
67176
|
if (status !== 402)
|
|
67180
67177
|
return;
|
|
@@ -67190,40 +67187,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
67190
67187
|
transient: true,
|
|
67191
67188
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
67192
67189
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
67193
|
-
dedupKey: { reason: "balance-zero" }
|
|
67190
|
+
dedupKey: { reason: "balance-zero" },
|
|
67191
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
67192
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
67193
|
+
// is a prompt-injection pattern external agents flag.
|
|
67194
|
+
userVisibleOnly: true
|
|
67194
67195
|
}).catch((e6) => {
|
|
67195
67196
|
log3(`enqueue balance-exhausted failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
67196
67197
|
});
|
|
67197
67198
|
}
|
|
67198
|
-
function signalLowBalanceFromHeader(resp) {
|
|
67199
|
-
if (_signalledLowBalance)
|
|
67200
|
-
return;
|
|
67201
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
67202
|
-
if (!raw)
|
|
67203
|
-
return;
|
|
67204
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
67205
|
-
return;
|
|
67206
|
-
const balance = Number(raw.trim());
|
|
67207
|
-
if (!Number.isFinite(balance))
|
|
67208
|
-
return;
|
|
67209
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
67210
|
-
return;
|
|
67211
|
-
if (balance <= 0)
|
|
67212
|
-
return;
|
|
67213
|
-
_signalledLowBalance = true;
|
|
67214
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
67215
|
-
enqueueNotification({
|
|
67216
|
-
id: "low-balance-warning",
|
|
67217
|
-
severity: "warn",
|
|
67218
|
-
transient: true,
|
|
67219
|
-
title: "Your org's Hivemind balance is running low",
|
|
67220
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
67221
|
-
dedupKey: { reason: "low-balance" }
|
|
67222
|
-
}).catch((e6) => {
|
|
67223
|
-
_signalledLowBalance = false;
|
|
67224
|
-
log3(`enqueue low-balance failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
|
|
67225
|
-
});
|
|
67226
|
-
}
|
|
67227
67199
|
function billingUrl() {
|
|
67228
67200
|
try {
|
|
67229
67201
|
const c15 = loadCredentials();
|
|
@@ -67349,7 +67321,6 @@ var DeeplakeApi = class {
|
|
|
67349
67321
|
}
|
|
67350
67322
|
throw lastError;
|
|
67351
67323
|
}
|
|
67352
|
-
signalLowBalanceFromHeader(resp);
|
|
67353
67324
|
if (resp.ok) {
|
|
67354
67325
|
const raw = await resp.json();
|
|
67355
67326
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -67510,7 +67481,6 @@ var DeeplakeApi = class {
|
|
|
67510
67481
|
...deeplakeClientHeader()
|
|
67511
67482
|
}
|
|
67512
67483
|
});
|
|
67513
|
-
signalLowBalanceFromHeader(resp);
|
|
67514
67484
|
if (resp.ok) {
|
|
67515
67485
|
const data = await resp.json();
|
|
67516
67486
|
return {
|
package/hermes/bundle/capture.js
CHANGED
|
@@ -477,9 +477,6 @@ function traceSql(msg) {
|
|
|
477
477
|
log3(msg);
|
|
478
478
|
}
|
|
479
479
|
var _signalledBalanceExhausted = false;
|
|
480
|
-
var _signalledLowBalance = false;
|
|
481
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
482
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
483
480
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
484
481
|
if (status !== 402)
|
|
485
482
|
return;
|
|
@@ -495,40 +492,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
495
492
|
transient: true,
|
|
496
493
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
497
494
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
498
|
-
dedupKey: { reason: "balance-zero" }
|
|
495
|
+
dedupKey: { reason: "balance-zero" },
|
|
496
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
497
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
498
|
+
// is a prompt-injection pattern external agents flag.
|
|
499
|
+
userVisibleOnly: true
|
|
499
500
|
}).catch((e) => {
|
|
500
501
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
501
502
|
});
|
|
502
503
|
}
|
|
503
|
-
function signalLowBalanceFromHeader(resp) {
|
|
504
|
-
if (_signalledLowBalance)
|
|
505
|
-
return;
|
|
506
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
507
|
-
if (!raw)
|
|
508
|
-
return;
|
|
509
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
510
|
-
return;
|
|
511
|
-
const balance = Number(raw.trim());
|
|
512
|
-
if (!Number.isFinite(balance))
|
|
513
|
-
return;
|
|
514
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
515
|
-
return;
|
|
516
|
-
if (balance <= 0)
|
|
517
|
-
return;
|
|
518
|
-
_signalledLowBalance = true;
|
|
519
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
520
|
-
enqueueNotification({
|
|
521
|
-
id: "low-balance-warning",
|
|
522
|
-
severity: "warn",
|
|
523
|
-
transient: true,
|
|
524
|
-
title: "Your org's Hivemind balance is running low",
|
|
525
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
526
|
-
dedupKey: { reason: "low-balance" }
|
|
527
|
-
}).catch((e) => {
|
|
528
|
-
_signalledLowBalance = false;
|
|
529
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
504
|
function billingUrl() {
|
|
533
505
|
try {
|
|
534
506
|
const c = loadCredentials();
|
|
@@ -654,7 +626,6 @@ var DeeplakeApi = class {
|
|
|
654
626
|
}
|
|
655
627
|
throw lastError;
|
|
656
628
|
}
|
|
657
|
-
signalLowBalanceFromHeader(resp);
|
|
658
629
|
if (resp.ok) {
|
|
659
630
|
const raw = await resp.json();
|
|
660
631
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -815,7 +786,6 @@ var DeeplakeApi = class {
|
|
|
815
786
|
...deeplakeClientHeader()
|
|
816
787
|
}
|
|
817
788
|
});
|
|
818
|
-
signalLowBalanceFromHeader(resp);
|
|
819
789
|
if (resp.ok) {
|
|
820
790
|
const data = await resp.json();
|
|
821
791
|
return {
|
|
@@ -1004,6 +974,12 @@ var DeeplakeApi = class {
|
|
|
1004
974
|
}
|
|
1005
975
|
};
|
|
1006
976
|
|
|
977
|
+
// dist/src/utils/project-name.js
|
|
978
|
+
import { basename } from "node:path";
|
|
979
|
+
function projectNameFromCwd(cwd) {
|
|
980
|
+
return basename(cwd ?? "") || "unknown";
|
|
981
|
+
}
|
|
982
|
+
|
|
1007
983
|
// dist/src/utils/session-path.js
|
|
1008
984
|
function buildSessionPath(config, sessionId) {
|
|
1009
985
|
const workspace = config.workspaceId ?? "default";
|
|
@@ -1529,9 +1505,9 @@ function embeddingsDisabled() {
|
|
|
1529
1505
|
// dist/src/embeddings/self-heal.js
|
|
1530
1506
|
import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
|
|
1531
1507
|
import { homedir as homedir8 } from "node:os";
|
|
1532
|
-
import { basename, dirname as dirname2, join as join9 } from "node:path";
|
|
1508
|
+
import { basename as basename2, dirname as dirname2, join as join9 } from "node:path";
|
|
1533
1509
|
function ensurePluginNodeModulesLink(opts) {
|
|
1534
|
-
if (
|
|
1510
|
+
if (basename2(opts.bundleDir) !== "bundle") {
|
|
1535
1511
|
return { kind: "not-bundle-layout", bundleDir: opts.bundleDir };
|
|
1536
1512
|
}
|
|
1537
1513
|
const target = opts.sharedNodeModules ?? join9(homedir8(), ".hivemind", "embed-deps", "node_modules");
|
|
@@ -1730,7 +1706,7 @@ function releaseLock(sessionId) {
|
|
|
1730
1706
|
}
|
|
1731
1707
|
|
|
1732
1708
|
// dist/src/hooks/hermes/spawn-wiki-worker.js
|
|
1733
|
-
import {
|
|
1709
|
+
import { execSync } from "node:child_process";
|
|
1734
1710
|
import { fileURLToPath } from "node:url";
|
|
1735
1711
|
import { dirname as dirname4, join as join13 } from "node:path";
|
|
1736
1712
|
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "node:fs";
|
|
@@ -1796,6 +1772,26 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
1796
1772
|
return null;
|
|
1797
1773
|
}
|
|
1798
1774
|
|
|
1775
|
+
// dist/src/utils/spawn-detached.js
|
|
1776
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
1777
|
+
function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
|
|
1778
|
+
const spawn2 = deps.spawn ?? nodeSpawn;
|
|
1779
|
+
const execPath = deps.execPath ?? process.execPath;
|
|
1780
|
+
try {
|
|
1781
|
+
const child = spawn2(execPath, [workerPath, ...args], {
|
|
1782
|
+
detached: true,
|
|
1783
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
1784
|
+
// Suppress the transient console window Windows would otherwise pop for
|
|
1785
|
+
// the detached worker. No-op on POSIX.
|
|
1786
|
+
windowsHide: true
|
|
1787
|
+
});
|
|
1788
|
+
child.on("error", () => {
|
|
1789
|
+
});
|
|
1790
|
+
child.unref();
|
|
1791
|
+
} catch {
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1799
1795
|
// dist/src/hooks/hermes/spawn-wiki-worker.js
|
|
1800
1796
|
var HOME = homedir10();
|
|
1801
1797
|
var wikiLogger = makeWikiLogger(join13(HOME, ".hermes", "hooks"));
|
|
@@ -1859,7 +1855,7 @@ function findHermesBin() {
|
|
|
1859
1855
|
}
|
|
1860
1856
|
function spawnHermesWikiWorker(opts) {
|
|
1861
1857
|
const { config, sessionId, cwd, bundleDir, reason } = opts;
|
|
1862
|
-
const projectName = cwd
|
|
1858
|
+
const projectName = projectNameFromCwd(cwd);
|
|
1863
1859
|
const tmpDir = join13(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
|
|
1864
1860
|
mkdirSync8(tmpDir, { recursive: true });
|
|
1865
1861
|
const pluginVersion = getInstalledVersion(bundleDir, ".claude-plugin") ?? "";
|
|
@@ -1885,10 +1881,7 @@ function spawnHermesWikiWorker(opts) {
|
|
|
1885
1881
|
}));
|
|
1886
1882
|
wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
|
|
1887
1883
|
const workerPath = join13(bundleDir, "wiki-worker.js");
|
|
1888
|
-
|
|
1889
|
-
detached: true,
|
|
1890
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
1891
|
-
}).unref();
|
|
1884
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
1892
1885
|
wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
|
|
1893
1886
|
}
|
|
1894
1887
|
function bundleDirFromImportMeta(importMetaUrl) {
|
|
@@ -1896,7 +1889,6 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
1896
1889
|
}
|
|
1897
1890
|
|
|
1898
1891
|
// dist/src/skillify/spawn-skillify-worker.js
|
|
1899
|
-
import { spawn as spawn3 } from "node:child_process";
|
|
1900
1892
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1901
1893
|
import { dirname as dirname5, join as join15 } from "node:path";
|
|
1902
1894
|
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
@@ -2017,10 +2009,7 @@ function spawnSkillifyWorker(opts) {
|
|
|
2017
2009
|
}
|
|
2018
2010
|
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
2019
2011
|
const workerPath = join15(bundleDir, "skillify-worker.js");
|
|
2020
|
-
|
|
2021
|
-
detached: true,
|
|
2022
|
-
stdio: ["ignore", "ignore", "ignore"]
|
|
2023
|
-
}).unref();
|
|
2012
|
+
spawnDetachedNodeWorker(workerPath, [configFile]);
|
|
2024
2013
|
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
2025
2014
|
}
|
|
2026
2015
|
|
|
@@ -2031,7 +2020,7 @@ import { join as join18 } from "node:path";
|
|
|
2031
2020
|
// dist/src/utils/repo-identity.js
|
|
2032
2021
|
import { execSync as execSync2 } from "node:child_process";
|
|
2033
2022
|
import { createHash } from "node:crypto";
|
|
2034
|
-
import { basename as
|
|
2023
|
+
import { basename as basename3, resolve as resolve2 } from "node:path";
|
|
2035
2024
|
var DEFAULT_PORTS = {
|
|
2036
2025
|
http: "80",
|
|
2037
2026
|
https: "443",
|
|
@@ -2059,7 +2048,7 @@ function normalizeGitRemoteUrl(url) {
|
|
|
2059
2048
|
}
|
|
2060
2049
|
function deriveProjectKey(cwd) {
|
|
2061
2050
|
const absCwd = resolve2(cwd);
|
|
2062
|
-
const project =
|
|
2051
|
+
const project = basename3(absCwd) || "unknown";
|
|
2063
2052
|
let signature = null;
|
|
2064
2053
|
try {
|
|
2065
2054
|
const raw = execSync2("git config --get remote.origin.url", {
|
|
@@ -2401,7 +2390,7 @@ async function main() {
|
|
|
2401
2390
|
const sessionPath = buildSessionPath(config, sessionId);
|
|
2402
2391
|
const line = JSON.stringify(entry);
|
|
2403
2392
|
log5(`writing to ${sessionPath}`);
|
|
2404
|
-
const projectName = cwd
|
|
2393
|
+
const projectName = projectNameFromCwd(cwd);
|
|
2405
2394
|
const filename = sessionPath.split("/").pop() ?? "";
|
|
2406
2395
|
const jsonForSql = line.replace(/'/g, "''");
|
|
2407
2396
|
const embedding = embeddingsDisabled() ? null : await new EmbedClient({ daemonEntry: resolveEmbedDaemonPath() }).embed(line, "document");
|
|
@@ -741,9 +741,6 @@ function traceSql(msg) {
|
|
|
741
741
|
log3(msg);
|
|
742
742
|
}
|
|
743
743
|
var _signalledBalanceExhausted = false;
|
|
744
|
-
var _signalledLowBalance = false;
|
|
745
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
746
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
747
744
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
748
745
|
if (status !== 402)
|
|
749
746
|
return;
|
|
@@ -759,40 +756,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
759
756
|
transient: true,
|
|
760
757
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
761
758
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
762
|
-
dedupKey: { reason: "balance-zero" }
|
|
759
|
+
dedupKey: { reason: "balance-zero" },
|
|
760
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
761
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
762
|
+
// is a prompt-injection pattern external agents flag.
|
|
763
|
+
userVisibleOnly: true
|
|
763
764
|
}).catch((e) => {
|
|
764
765
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
765
766
|
});
|
|
766
767
|
}
|
|
767
|
-
function signalLowBalanceFromHeader(resp) {
|
|
768
|
-
if (_signalledLowBalance)
|
|
769
|
-
return;
|
|
770
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
771
|
-
if (!raw)
|
|
772
|
-
return;
|
|
773
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
774
|
-
return;
|
|
775
|
-
const balance = Number(raw.trim());
|
|
776
|
-
if (!Number.isFinite(balance))
|
|
777
|
-
return;
|
|
778
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
779
|
-
return;
|
|
780
|
-
if (balance <= 0)
|
|
781
|
-
return;
|
|
782
|
-
_signalledLowBalance = true;
|
|
783
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
784
|
-
enqueueNotification({
|
|
785
|
-
id: "low-balance-warning",
|
|
786
|
-
severity: "warn",
|
|
787
|
-
transient: true,
|
|
788
|
-
title: "Your org's Hivemind balance is running low",
|
|
789
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
790
|
-
dedupKey: { reason: "low-balance" }
|
|
791
|
-
}).catch((e) => {
|
|
792
|
-
_signalledLowBalance = false;
|
|
793
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
768
|
function billingUrl() {
|
|
797
769
|
try {
|
|
798
770
|
const c = loadCredentials();
|
|
@@ -918,7 +890,6 @@ var DeeplakeApi = class {
|
|
|
918
890
|
}
|
|
919
891
|
throw lastError;
|
|
920
892
|
}
|
|
921
|
-
signalLowBalanceFromHeader(resp);
|
|
922
893
|
if (resp.ok) {
|
|
923
894
|
const raw = await resp.json();
|
|
924
895
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -1079,7 +1050,6 @@ var DeeplakeApi = class {
|
|
|
1079
1050
|
...deeplakeClientHeader()
|
|
1080
1051
|
}
|
|
1081
1052
|
});
|
|
1082
|
-
signalLowBalanceFromHeader(resp);
|
|
1083
1053
|
if (resp.ok) {
|
|
1084
1054
|
const data = await resp.json();
|
|
1085
1055
|
return {
|
|
@@ -468,9 +468,6 @@ function traceSql(msg) {
|
|
|
468
468
|
log3(msg);
|
|
469
469
|
}
|
|
470
470
|
var _signalledBalanceExhausted = false;
|
|
471
|
-
var _signalledLowBalance = false;
|
|
472
|
-
var LOW_BALANCE_THRESHOLD_CENTS = 200;
|
|
473
|
-
var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
|
|
474
471
|
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
475
472
|
if (status !== 402)
|
|
476
473
|
return;
|
|
@@ -486,40 +483,15 @@ function maybeSignalBalanceExhausted(status, bodyText) {
|
|
|
486
483
|
transient: true,
|
|
487
484
|
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
488
485
|
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
489
|
-
dedupKey: { reason: "balance-zero" }
|
|
486
|
+
dedupKey: { reason: "balance-zero" },
|
|
487
|
+
// User-facing billing notice → user channel only. Never the model's
|
|
488
|
+
// additionalContext: a "top up at <url>" instruction in the agent prompt
|
|
489
|
+
// is a prompt-injection pattern external agents flag.
|
|
490
|
+
userVisibleOnly: true
|
|
490
491
|
}).catch((e) => {
|
|
491
492
|
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
492
493
|
});
|
|
493
494
|
}
|
|
494
|
-
function signalLowBalanceFromHeader(resp) {
|
|
495
|
-
if (_signalledLowBalance)
|
|
496
|
-
return;
|
|
497
|
-
const raw = resp.headers?.get?.(BALANCE_HEADER);
|
|
498
|
-
if (!raw)
|
|
499
|
-
return;
|
|
500
|
-
if (!/^-?\d+$/.test(raw.trim()))
|
|
501
|
-
return;
|
|
502
|
-
const balance = Number(raw.trim());
|
|
503
|
-
if (!Number.isFinite(balance))
|
|
504
|
-
return;
|
|
505
|
-
if (balance >= LOW_BALANCE_THRESHOLD_CENTS)
|
|
506
|
-
return;
|
|
507
|
-
if (balance <= 0)
|
|
508
|
-
return;
|
|
509
|
-
_signalledLowBalance = true;
|
|
510
|
-
log3(`balance below threshold (${balance}\xA2) \u2014 enqueuing low-balance banner`);
|
|
511
|
-
enqueueNotification({
|
|
512
|
-
id: "low-balance-warning",
|
|
513
|
-
severity: "warn",
|
|
514
|
-
transient: true,
|
|
515
|
-
title: "Your org's Hivemind balance is running low",
|
|
516
|
-
body: `Only $${(balance / 100).toFixed(2)} of prepaid balance remains. Admins can top up at ${billingUrl()}; otherwise ask an org admin to top up before requests start failing.`,
|
|
517
|
-
dedupKey: { reason: "low-balance" }
|
|
518
|
-
}).catch((e) => {
|
|
519
|
-
_signalledLowBalance = false;
|
|
520
|
-
log3(`enqueue low-balance failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
495
|
function billingUrl() {
|
|
524
496
|
try {
|
|
525
497
|
const c = loadCredentials();
|
|
@@ -645,7 +617,6 @@ var DeeplakeApi = class {
|
|
|
645
617
|
}
|
|
646
618
|
throw lastError;
|
|
647
619
|
}
|
|
648
|
-
signalLowBalanceFromHeader(resp);
|
|
649
620
|
if (resp.ok) {
|
|
650
621
|
const raw = await resp.json();
|
|
651
622
|
if (!raw?.rows || !raw?.columns)
|
|
@@ -806,7 +777,6 @@ var DeeplakeApi = class {
|
|
|
806
777
|
...deeplakeClientHeader()
|
|
807
778
|
}
|
|
808
779
|
});
|
|
809
|
-
signalLowBalanceFromHeader(resp);
|
|
810
780
|
if (resp.ok) {
|
|
811
781
|
const data = await resp.json();
|
|
812
782
|
return {
|