@deeplake/hivemind 0.7.16 → 0.7.18
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +294 -105
- package/codex/bundle/session-start.js +1154 -25
- package/codex/bundle/{skilify-worker.js → skillify-worker.js} +65 -30
- package/codex/bundle/stop.js +105 -68
- package/cursor/bundle/capture.js +84 -47
- package/cursor/bundle/session-end.js +82 -45
- package/cursor/bundle/session-start.js +633 -25
- package/cursor/bundle/{skilify-worker.js → skillify-worker.js} +65 -30
- package/hermes/bundle/capture.js +84 -47
- package/hermes/bundle/session-end.js +82 -45
- package/hermes/bundle/session-start.js +631 -23
- package/hermes/bundle/{skilify-worker.js → skillify-worker.js} +65 -30
- package/openclaw/dist/index.js +47 -30
- package/openclaw/dist/{skilify-worker.js → skillify-worker.js} +65 -30
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/openclaw/skills/SKILL.md +19 -19
- package/package.json +1 -1
- package/pi/extension-source/hivemind.ts +94 -45
|
@@ -229,14 +229,14 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
229
229
|
return dirname(fileURLToPath(importMetaUrl));
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
// dist/src/
|
|
232
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
233
233
|
import { spawn as spawn2 } from "node:child_process";
|
|
234
234
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
235
235
|
import { dirname as dirname2, join as join7 } from "node:path";
|
|
236
236
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
237
237
|
import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
|
|
238
238
|
|
|
239
|
-
// dist/src/
|
|
239
|
+
// dist/src/skillify/gate-runner.js
|
|
240
240
|
import { execFileSync } from "node:child_process";
|
|
241
241
|
import { existsSync as existsSync3 } from "node:fs";
|
|
242
242
|
import { homedir as homedir5 } from "node:os";
|
|
@@ -267,20 +267,20 @@ function findAgentBin(agent) {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
// dist/src/
|
|
270
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
271
271
|
var HOME2 = homedir6();
|
|
272
|
-
var
|
|
273
|
-
function
|
|
272
|
+
var SKILLIFY_LOG = join7(HOME2, ".claude", "hooks", "skillify.log");
|
|
273
|
+
function skillifyLog(msg) {
|
|
274
274
|
try {
|
|
275
|
-
mkdirSync4(dirname2(
|
|
276
|
-
appendFileSync3(
|
|
275
|
+
mkdirSync4(dirname2(SKILLIFY_LOG), { recursive: true });
|
|
276
|
+
appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
|
|
277
277
|
`);
|
|
278
278
|
} catch {
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
function
|
|
281
|
+
function spawnSkillifyWorker(opts) {
|
|
282
282
|
const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
|
|
283
|
-
const tmpDir = join7(tmpdir2(), `deeplake-
|
|
283
|
+
const tmpDir = join7(tmpdir2(), `deeplake-skillify-${projectKey}-${Date.now()}`);
|
|
284
284
|
mkdirSync4(tmpDir, { recursive: true, mode: 448 });
|
|
285
285
|
const gateBin = findAgentBin(agent);
|
|
286
286
|
const configFile = join7(tmpDir, "config.json");
|
|
@@ -306,40 +306,72 @@ function spawnSkilifyWorker(opts) {
|
|
|
306
306
|
hermesModel: process.env.HIVEMIND_HERMES_MODEL,
|
|
307
307
|
piProvider: process.env.HIVEMIND_PI_PROVIDER,
|
|
308
308
|
piModel: process.env.HIVEMIND_PI_MODEL,
|
|
309
|
-
|
|
309
|
+
skillifyLog: SKILLIFY_LOG,
|
|
310
310
|
currentSessionId
|
|
311
311
|
}), { mode: 384 });
|
|
312
312
|
try {
|
|
313
313
|
chmodSync(configFile, 384);
|
|
314
314
|
} catch {
|
|
315
315
|
}
|
|
316
|
-
|
|
317
|
-
const workerPath = join7(bundleDir, "
|
|
316
|
+
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
317
|
+
const workerPath = join7(bundleDir, "skillify-worker.js");
|
|
318
318
|
spawn2("nohup", ["node", workerPath, configFile], {
|
|
319
319
|
detached: true,
|
|
320
320
|
stdio: ["ignore", "ignore", "ignore"]
|
|
321
321
|
}).unref();
|
|
322
|
-
|
|
322
|
+
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
-
// dist/src/
|
|
326
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, writeSync as writeSync2, mkdirSync as mkdirSync5, renameSync as
|
|
325
|
+
// dist/src/skillify/state.js
|
|
326
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, writeSync as writeSync2, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync5, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
|
|
327
327
|
import { execSync as execSync2 } from "node:child_process";
|
|
328
|
-
import { homedir as
|
|
328
|
+
import { homedir as homedir8 } from "node:os";
|
|
329
329
|
import { createHash } from "node:crypto";
|
|
330
|
-
import { join as
|
|
331
|
-
|
|
332
|
-
|
|
330
|
+
import { join as join9, basename } from "node:path";
|
|
331
|
+
|
|
332
|
+
// dist/src/skillify/legacy-migration.js
|
|
333
|
+
import { existsSync as existsSync4, renameSync as renameSync2 } from "node:fs";
|
|
334
|
+
import { homedir as homedir7 } from "node:os";
|
|
335
|
+
import { join as join8 } from "node:path";
|
|
336
|
+
var dlog2 = (msg) => log("skillify-migrate", msg);
|
|
337
|
+
var attempted = false;
|
|
338
|
+
function migrateLegacyStateDir() {
|
|
339
|
+
if (attempted)
|
|
340
|
+
return;
|
|
341
|
+
attempted = true;
|
|
342
|
+
const root = join8(homedir7(), ".deeplake", "state");
|
|
343
|
+
const legacy = join8(root, "skilify");
|
|
344
|
+
const current = join8(root, "skillify");
|
|
345
|
+
if (!existsSync4(legacy))
|
|
346
|
+
return;
|
|
347
|
+
if (existsSync4(current))
|
|
348
|
+
return;
|
|
349
|
+
try {
|
|
350
|
+
renameSync2(legacy, current);
|
|
351
|
+
dlog2(`migrated ${legacy} -> ${current}`);
|
|
352
|
+
} catch (err) {
|
|
353
|
+
const code = err.code;
|
|
354
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
355
|
+
dlog2(`migration failed (${code}); leaving legacy dir in place`);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
throw err;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// dist/src/skillify/state.js
|
|
363
|
+
var dlog3 = (msg) => log("skillify-state", msg);
|
|
364
|
+
var STATE_DIR2 = join9(homedir8(), ".deeplake", "state", "skillify");
|
|
333
365
|
var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
|
|
334
366
|
var TRIGGER_THRESHOLD = (() => {
|
|
335
|
-
const n = Number(process.env.
|
|
367
|
+
const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
|
|
336
368
|
return Number.isInteger(n) && n > 0 ? n : 20;
|
|
337
369
|
})();
|
|
338
370
|
function statePath(projectKey) {
|
|
339
|
-
return
|
|
371
|
+
return join9(STATE_DIR2, `${projectKey}.json`);
|
|
340
372
|
}
|
|
341
373
|
function lockPath2(projectKey) {
|
|
342
|
-
return
|
|
374
|
+
return join9(STATE_DIR2, `${projectKey}.lock`);
|
|
343
375
|
}
|
|
344
376
|
function deriveProjectKey(cwd) {
|
|
345
377
|
const project = basename(cwd) || "unknown";
|
|
@@ -357,8 +389,9 @@ function deriveProjectKey(cwd) {
|
|
|
357
389
|
return { key, project };
|
|
358
390
|
}
|
|
359
391
|
function readState(projectKey) {
|
|
392
|
+
migrateLegacyStateDir();
|
|
360
393
|
const p = statePath(projectKey);
|
|
361
|
-
if (!
|
|
394
|
+
if (!existsSync5(p))
|
|
362
395
|
return null;
|
|
363
396
|
try {
|
|
364
397
|
return JSON.parse(readFileSync3(p, "utf-8"));
|
|
@@ -367,13 +400,15 @@ function readState(projectKey) {
|
|
|
367
400
|
}
|
|
368
401
|
}
|
|
369
402
|
function writeState(projectKey, state) {
|
|
403
|
+
migrateLegacyStateDir();
|
|
370
404
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
371
405
|
const p = statePath(projectKey);
|
|
372
406
|
const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
|
|
373
407
|
writeFileSync4(tmp, JSON.stringify(state, null, 2));
|
|
374
|
-
|
|
408
|
+
renameSync3(tmp, p);
|
|
375
409
|
}
|
|
376
410
|
function withRmwLock(projectKey, fn) {
|
|
411
|
+
migrateLegacyStateDir();
|
|
377
412
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
378
413
|
const rmw = lockPath2(projectKey) + ".rmw";
|
|
379
414
|
const deadline = Date.now() + 2e3;
|
|
@@ -385,11 +420,11 @@ function withRmwLock(projectKey, fn) {
|
|
|
385
420
|
if (e.code !== "EEXIST")
|
|
386
421
|
throw e;
|
|
387
422
|
if (Date.now() > deadline) {
|
|
388
|
-
|
|
423
|
+
dlog3(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
|
|
389
424
|
try {
|
|
390
425
|
unlinkSync2(rmw);
|
|
391
426
|
} catch (unlinkErr) {
|
|
392
|
-
|
|
427
|
+
dlog3(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
|
|
393
428
|
}
|
|
394
429
|
continue;
|
|
395
430
|
}
|
|
@@ -403,7 +438,7 @@ function withRmwLock(projectKey, fn) {
|
|
|
403
438
|
try {
|
|
404
439
|
unlinkSync2(rmw);
|
|
405
440
|
} catch (unlinkErr) {
|
|
406
|
-
|
|
441
|
+
dlog3(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
|
|
407
442
|
}
|
|
408
443
|
}
|
|
409
444
|
}
|
|
@@ -416,20 +451,21 @@ function resetCounter(projectKey) {
|
|
|
416
451
|
});
|
|
417
452
|
}
|
|
418
453
|
function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
|
|
454
|
+
migrateLegacyStateDir();
|
|
419
455
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
420
456
|
const p = lockPath2(projectKey);
|
|
421
|
-
if (
|
|
457
|
+
if (existsSync5(p)) {
|
|
422
458
|
try {
|
|
423
459
|
const ageMs = Date.now() - parseInt(readFileSync3(p, "utf-8"), 10);
|
|
424
460
|
if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
|
|
425
461
|
return false;
|
|
426
462
|
} catch (readErr) {
|
|
427
|
-
|
|
463
|
+
dlog3(`worker lock unreadable for ${projectKey}, treating as stale: ${readErr.message}`);
|
|
428
464
|
}
|
|
429
465
|
try {
|
|
430
466
|
unlinkSync2(p);
|
|
431
467
|
} catch (unlinkErr) {
|
|
432
|
-
|
|
468
|
+
dlog3(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
|
|
433
469
|
return false;
|
|
434
470
|
}
|
|
435
471
|
}
|
|
@@ -453,15 +489,16 @@ function releaseWorkerLock(projectKey) {
|
|
|
453
489
|
}
|
|
454
490
|
}
|
|
455
491
|
|
|
456
|
-
// dist/src/
|
|
457
|
-
import { existsSync as
|
|
458
|
-
import { homedir as
|
|
459
|
-
import { join as
|
|
460
|
-
var STATE_DIR3 =
|
|
461
|
-
var CONFIG_PATH =
|
|
492
|
+
// dist/src/skillify/scope-config.js
|
|
493
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
494
|
+
import { homedir as homedir9 } from "node:os";
|
|
495
|
+
import { join as join10 } from "node:path";
|
|
496
|
+
var STATE_DIR3 = join10(homedir9(), ".deeplake", "state", "skillify");
|
|
497
|
+
var CONFIG_PATH = join10(STATE_DIR3, "config.json");
|
|
462
498
|
var DEFAULT = { scope: "me", team: [], install: "project" };
|
|
463
499
|
function loadScopeConfig() {
|
|
464
|
-
|
|
500
|
+
migrateLegacyStateDir();
|
|
501
|
+
if (!existsSync6(CONFIG_PATH))
|
|
465
502
|
return DEFAULT;
|
|
466
503
|
try {
|
|
467
504
|
const raw = JSON.parse(readFileSync4(CONFIG_PATH, "utf-8"));
|
|
@@ -474,24 +511,24 @@ function loadScopeConfig() {
|
|
|
474
511
|
}
|
|
475
512
|
}
|
|
476
513
|
|
|
477
|
-
// dist/src/
|
|
514
|
+
// dist/src/skillify/triggers.js
|
|
478
515
|
function forceSessionEndTrigger(opts) {
|
|
479
|
-
if (process.env.
|
|
516
|
+
if (process.env.HIVEMIND_SKILLIFY_WORKER === "1")
|
|
480
517
|
return;
|
|
481
518
|
if (!opts.cwd)
|
|
482
519
|
return;
|
|
483
520
|
try {
|
|
484
521
|
const { key: projectKey, project } = deriveProjectKey(opts.cwd);
|
|
485
522
|
if (!tryAcquireWorkerLock(projectKey)) {
|
|
486
|
-
|
|
523
|
+
skillifyLog(`SessionEnd: skillify worker already running for ${projectKey}, skipping`);
|
|
487
524
|
return;
|
|
488
525
|
}
|
|
489
526
|
if (readState(projectKey)) {
|
|
490
527
|
resetCounter(projectKey);
|
|
491
528
|
}
|
|
492
|
-
|
|
529
|
+
skillifyLog(`SessionEnd: spawning skillify worker for project=${project} agent=${opts.agent}`);
|
|
493
530
|
try {
|
|
494
|
-
|
|
531
|
+
spawnSkillifyWorker({
|
|
495
532
|
config: opts.config,
|
|
496
533
|
cwd: opts.cwd,
|
|
497
534
|
projectKey,
|
|
@@ -503,14 +540,14 @@ function forceSessionEndTrigger(opts) {
|
|
|
503
540
|
reason: "SessionEnd"
|
|
504
541
|
});
|
|
505
542
|
} catch (e) {
|
|
506
|
-
|
|
543
|
+
skillifyLog(`SessionEnd spawn failed: ${e?.message ?? e}`);
|
|
507
544
|
try {
|
|
508
545
|
releaseWorkerLock(projectKey);
|
|
509
546
|
} catch {
|
|
510
547
|
}
|
|
511
548
|
}
|
|
512
549
|
} catch (e) {
|
|
513
|
-
|
|
550
|
+
skillifyLog(`SessionEnd trigger error: ${e?.message ?? e}`);
|
|
514
551
|
}
|
|
515
552
|
}
|
|
516
553
|
|
|
@@ -554,7 +591,7 @@ async function main() {
|
|
|
554
591
|
sessionId
|
|
555
592
|
});
|
|
556
593
|
} catch (e) {
|
|
557
|
-
wikiLog(`SessionEnd:
|
|
594
|
+
wikiLog(`SessionEnd: skillify trigger failed: ${e?.message ?? e}`);
|
|
558
595
|
}
|
|
559
596
|
}
|
|
560
597
|
main().catch((e) => {
|