@deeplake/hivemind 0.7.17 → 0.7.19
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 +148 -111
- package/codex/bundle/session-start.js +89 -55
- 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 +87 -53
- 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 +87 -53
- 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 +43 -43
package/cursor/bundle/capture.js
CHANGED
|
@@ -839,7 +839,7 @@ function embeddingsDisabled() {
|
|
|
839
839
|
|
|
840
840
|
// dist/src/hooks/cursor/capture.js
|
|
841
841
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
842
|
-
import { dirname as dirname3, join as
|
|
842
|
+
import { dirname as dirname3, join as join14 } from "node:path";
|
|
843
843
|
|
|
844
844
|
// dist/src/hooks/summary-state.js
|
|
845
845
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, writeSync as writeSync2, mkdirSync as mkdirSync2, renameSync, existsSync as existsSync4, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
|
|
@@ -1096,14 +1096,14 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
1096
1096
|
return dirname(fileURLToPath(importMetaUrl));
|
|
1097
1097
|
}
|
|
1098
1098
|
|
|
1099
|
-
// dist/src/
|
|
1099
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
1100
1100
|
import { spawn as spawn3 } from "node:child_process";
|
|
1101
1101
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1102
1102
|
import { dirname as dirname2, join as join10 } from "node:path";
|
|
1103
1103
|
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
1104
1104
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "node:os";
|
|
1105
1105
|
|
|
1106
|
-
// dist/src/
|
|
1106
|
+
// dist/src/skillify/gate-runner.js
|
|
1107
1107
|
import { execFileSync } from "node:child_process";
|
|
1108
1108
|
import { existsSync as existsSync5 } from "node:fs";
|
|
1109
1109
|
import { homedir as homedir7 } from "node:os";
|
|
@@ -1134,20 +1134,20 @@ function findAgentBin(agent) {
|
|
|
1134
1134
|
}
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
1137
|
-
// dist/src/
|
|
1137
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
1138
1138
|
var HOME2 = homedir8();
|
|
1139
|
-
var
|
|
1140
|
-
function
|
|
1139
|
+
var SKILLIFY_LOG = join10(HOME2, ".claude", "hooks", "skillify.log");
|
|
1140
|
+
function skillifyLog(msg) {
|
|
1141
1141
|
try {
|
|
1142
|
-
mkdirSync5(dirname2(
|
|
1143
|
-
appendFileSync3(
|
|
1142
|
+
mkdirSync5(dirname2(SKILLIFY_LOG), { recursive: true });
|
|
1143
|
+
appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
|
|
1144
1144
|
`);
|
|
1145
1145
|
} catch {
|
|
1146
1146
|
}
|
|
1147
1147
|
}
|
|
1148
|
-
function
|
|
1148
|
+
function spawnSkillifyWorker(opts) {
|
|
1149
1149
|
const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
|
|
1150
|
-
const tmpDir = join10(tmpdir3(), `deeplake-
|
|
1150
|
+
const tmpDir = join10(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
|
|
1151
1151
|
mkdirSync5(tmpDir, { recursive: true, mode: 448 });
|
|
1152
1152
|
const gateBin = findAgentBin(agent);
|
|
1153
1153
|
const configFile = join10(tmpDir, "config.json");
|
|
@@ -1173,40 +1173,72 @@ function spawnSkilifyWorker(opts) {
|
|
|
1173
1173
|
hermesModel: process.env.HIVEMIND_HERMES_MODEL,
|
|
1174
1174
|
piProvider: process.env.HIVEMIND_PI_PROVIDER,
|
|
1175
1175
|
piModel: process.env.HIVEMIND_PI_MODEL,
|
|
1176
|
-
|
|
1176
|
+
skillifyLog: SKILLIFY_LOG,
|
|
1177
1177
|
currentSessionId
|
|
1178
1178
|
}), { mode: 384 });
|
|
1179
1179
|
try {
|
|
1180
1180
|
chmodSync(configFile, 384);
|
|
1181
1181
|
} catch {
|
|
1182
1182
|
}
|
|
1183
|
-
|
|
1184
|
-
const workerPath = join10(bundleDir, "
|
|
1183
|
+
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
1184
|
+
const workerPath = join10(bundleDir, "skillify-worker.js");
|
|
1185
1185
|
spawn3("nohup", ["node", workerPath, configFile], {
|
|
1186
1186
|
detached: true,
|
|
1187
1187
|
stdio: ["ignore", "ignore", "ignore"]
|
|
1188
1188
|
}).unref();
|
|
1189
|
-
|
|
1189
|
+
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
1190
1190
|
}
|
|
1191
1191
|
|
|
1192
|
-
// dist/src/
|
|
1193
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, writeSync as writeSync3, mkdirSync as mkdirSync6, renameSync as
|
|
1192
|
+
// dist/src/skillify/state.js
|
|
1193
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, writeSync as writeSync3, mkdirSync as mkdirSync6, renameSync as renameSync3, existsSync as existsSync7, unlinkSync as unlinkSync3, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
|
|
1194
1194
|
import { execSync as execSync2 } from "node:child_process";
|
|
1195
|
-
import { homedir as
|
|
1195
|
+
import { homedir as homedir10 } from "node:os";
|
|
1196
1196
|
import { createHash } from "node:crypto";
|
|
1197
|
-
import { join as
|
|
1198
|
-
|
|
1199
|
-
|
|
1197
|
+
import { join as join12, basename } from "node:path";
|
|
1198
|
+
|
|
1199
|
+
// dist/src/skillify/legacy-migration.js
|
|
1200
|
+
import { existsSync as existsSync6, renameSync as renameSync2 } from "node:fs";
|
|
1201
|
+
import { homedir as homedir9 } from "node:os";
|
|
1202
|
+
import { join as join11 } from "node:path";
|
|
1203
|
+
var dlog2 = (msg) => log("skillify-migrate", msg);
|
|
1204
|
+
var attempted = false;
|
|
1205
|
+
function migrateLegacyStateDir() {
|
|
1206
|
+
if (attempted)
|
|
1207
|
+
return;
|
|
1208
|
+
attempted = true;
|
|
1209
|
+
const root = join11(homedir9(), ".deeplake", "state");
|
|
1210
|
+
const legacy = join11(root, "skilify");
|
|
1211
|
+
const current = join11(root, "skillify");
|
|
1212
|
+
if (!existsSync6(legacy))
|
|
1213
|
+
return;
|
|
1214
|
+
if (existsSync6(current))
|
|
1215
|
+
return;
|
|
1216
|
+
try {
|
|
1217
|
+
renameSync2(legacy, current);
|
|
1218
|
+
dlog2(`migrated ${legacy} -> ${current}`);
|
|
1219
|
+
} catch (err) {
|
|
1220
|
+
const code = err.code;
|
|
1221
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
1222
|
+
dlog2(`migration failed (${code}); leaving legacy dir in place`);
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
throw err;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
// dist/src/skillify/state.js
|
|
1230
|
+
var dlog3 = (msg) => log("skillify-state", msg);
|
|
1231
|
+
var STATE_DIR2 = join12(homedir10(), ".deeplake", "state", "skillify");
|
|
1200
1232
|
var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
|
|
1201
1233
|
var TRIGGER_THRESHOLD = (() => {
|
|
1202
|
-
const n = Number(process.env.
|
|
1234
|
+
const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
|
|
1203
1235
|
return Number.isInteger(n) && n > 0 ? n : 20;
|
|
1204
1236
|
})();
|
|
1205
1237
|
function statePath2(projectKey) {
|
|
1206
|
-
return
|
|
1238
|
+
return join12(STATE_DIR2, `${projectKey}.json`);
|
|
1207
1239
|
}
|
|
1208
1240
|
function lockPath2(projectKey) {
|
|
1209
|
-
return
|
|
1241
|
+
return join12(STATE_DIR2, `${projectKey}.lock`);
|
|
1210
1242
|
}
|
|
1211
1243
|
function deriveProjectKey(cwd) {
|
|
1212
1244
|
const project = basename(cwd) || "unknown";
|
|
@@ -1224,8 +1256,9 @@ function deriveProjectKey(cwd) {
|
|
|
1224
1256
|
return { key, project };
|
|
1225
1257
|
}
|
|
1226
1258
|
function readState2(projectKey) {
|
|
1259
|
+
migrateLegacyStateDir();
|
|
1227
1260
|
const p = statePath2(projectKey);
|
|
1228
|
-
if (!
|
|
1261
|
+
if (!existsSync7(p))
|
|
1229
1262
|
return null;
|
|
1230
1263
|
try {
|
|
1231
1264
|
return JSON.parse(readFileSync5(p, "utf-8"));
|
|
@@ -1234,13 +1267,15 @@ function readState2(projectKey) {
|
|
|
1234
1267
|
}
|
|
1235
1268
|
}
|
|
1236
1269
|
function writeState2(projectKey, state) {
|
|
1270
|
+
migrateLegacyStateDir();
|
|
1237
1271
|
mkdirSync6(STATE_DIR2, { recursive: true });
|
|
1238
1272
|
const p = statePath2(projectKey);
|
|
1239
1273
|
const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
|
|
1240
1274
|
writeFileSync5(tmp, JSON.stringify(state, null, 2));
|
|
1241
|
-
|
|
1275
|
+
renameSync3(tmp, p);
|
|
1242
1276
|
}
|
|
1243
1277
|
function withRmwLock2(projectKey, fn) {
|
|
1278
|
+
migrateLegacyStateDir();
|
|
1244
1279
|
mkdirSync6(STATE_DIR2, { recursive: true });
|
|
1245
1280
|
const rmw = lockPath2(projectKey) + ".rmw";
|
|
1246
1281
|
const deadline = Date.now() + 2e3;
|
|
@@ -1252,11 +1287,11 @@ function withRmwLock2(projectKey, fn) {
|
|
|
1252
1287
|
if (e.code !== "EEXIST")
|
|
1253
1288
|
throw e;
|
|
1254
1289
|
if (Date.now() > deadline) {
|
|
1255
|
-
|
|
1290
|
+
dlog3(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
|
|
1256
1291
|
try {
|
|
1257
1292
|
unlinkSync3(rmw);
|
|
1258
1293
|
} catch (unlinkErr) {
|
|
1259
|
-
|
|
1294
|
+
dlog3(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
|
|
1260
1295
|
}
|
|
1261
1296
|
continue;
|
|
1262
1297
|
}
|
|
@@ -1270,7 +1305,7 @@ function withRmwLock2(projectKey, fn) {
|
|
|
1270
1305
|
try {
|
|
1271
1306
|
unlinkSync3(rmw);
|
|
1272
1307
|
} catch (unlinkErr) {
|
|
1273
|
-
|
|
1308
|
+
dlog3(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
|
|
1274
1309
|
}
|
|
1275
1310
|
}
|
|
1276
1311
|
}
|
|
@@ -1300,20 +1335,21 @@ function resetCounter(projectKey) {
|
|
|
1300
1335
|
});
|
|
1301
1336
|
}
|
|
1302
1337
|
function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
|
|
1338
|
+
migrateLegacyStateDir();
|
|
1303
1339
|
mkdirSync6(STATE_DIR2, { recursive: true });
|
|
1304
1340
|
const p = lockPath2(projectKey);
|
|
1305
|
-
if (
|
|
1341
|
+
if (existsSync7(p)) {
|
|
1306
1342
|
try {
|
|
1307
1343
|
const ageMs = Date.now() - parseInt(readFileSync5(p, "utf-8"), 10);
|
|
1308
1344
|
if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
|
|
1309
1345
|
return false;
|
|
1310
1346
|
} catch (readErr) {
|
|
1311
|
-
|
|
1347
|
+
dlog3(`worker lock unreadable for ${projectKey}, treating as stale: ${readErr.message}`);
|
|
1312
1348
|
}
|
|
1313
1349
|
try {
|
|
1314
1350
|
unlinkSync3(p);
|
|
1315
1351
|
} catch (unlinkErr) {
|
|
1316
|
-
|
|
1352
|
+
dlog3(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
|
|
1317
1353
|
return false;
|
|
1318
1354
|
}
|
|
1319
1355
|
}
|
|
@@ -1337,15 +1373,16 @@ function releaseWorkerLock(projectKey) {
|
|
|
1337
1373
|
}
|
|
1338
1374
|
}
|
|
1339
1375
|
|
|
1340
|
-
// dist/src/
|
|
1341
|
-
import { existsSync as
|
|
1342
|
-
import { homedir as
|
|
1343
|
-
import { join as
|
|
1344
|
-
var STATE_DIR3 =
|
|
1345
|
-
var CONFIG_PATH =
|
|
1376
|
+
// dist/src/skillify/scope-config.js
|
|
1377
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
1378
|
+
import { homedir as homedir11 } from "node:os";
|
|
1379
|
+
import { join as join13 } from "node:path";
|
|
1380
|
+
var STATE_DIR3 = join13(homedir11(), ".deeplake", "state", "skillify");
|
|
1381
|
+
var CONFIG_PATH = join13(STATE_DIR3, "config.json");
|
|
1346
1382
|
var DEFAULT = { scope: "me", team: [], install: "project" };
|
|
1347
1383
|
function loadScopeConfig() {
|
|
1348
|
-
|
|
1384
|
+
migrateLegacyStateDir();
|
|
1385
|
+
if (!existsSync8(CONFIG_PATH))
|
|
1349
1386
|
return DEFAULT;
|
|
1350
1387
|
try {
|
|
1351
1388
|
const raw = JSON.parse(readFileSync6(CONFIG_PATH, "utf-8"));
|
|
@@ -1358,9 +1395,9 @@ function loadScopeConfig() {
|
|
|
1358
1395
|
}
|
|
1359
1396
|
}
|
|
1360
1397
|
|
|
1361
|
-
// dist/src/
|
|
1398
|
+
// dist/src/skillify/triggers.js
|
|
1362
1399
|
function tryStopCounterTrigger(opts) {
|
|
1363
|
-
if (process.env.
|
|
1400
|
+
if (process.env.HIVEMIND_SKILLIFY_WORKER === "1")
|
|
1364
1401
|
return;
|
|
1365
1402
|
if (!opts.cwd)
|
|
1366
1403
|
return;
|
|
@@ -1369,13 +1406,13 @@ function tryStopCounterTrigger(opts) {
|
|
|
1369
1406
|
if (state.counter < TRIGGER_THRESHOLD)
|
|
1370
1407
|
return;
|
|
1371
1408
|
if (!tryAcquireWorkerLock(state.projectKey)) {
|
|
1372
|
-
|
|
1409
|
+
skillifyLog(`Stop: trigger suppressed (worker lock held) project=${state.project}`);
|
|
1373
1410
|
return;
|
|
1374
1411
|
}
|
|
1375
|
-
|
|
1412
|
+
skillifyLog(`Stop: threshold hit (counter=${state.counter}, N=${TRIGGER_THRESHOLD}) project=${state.project} agent=${opts.agent}`);
|
|
1376
1413
|
resetCounter(state.projectKey);
|
|
1377
1414
|
try {
|
|
1378
|
-
|
|
1415
|
+
spawnSkillifyWorker({
|
|
1379
1416
|
config: opts.config,
|
|
1380
1417
|
cwd: opts.cwd,
|
|
1381
1418
|
projectKey: state.projectKey,
|
|
@@ -1387,21 +1424,21 @@ function tryStopCounterTrigger(opts) {
|
|
|
1387
1424
|
reason: "Stop"
|
|
1388
1425
|
});
|
|
1389
1426
|
} catch (e) {
|
|
1390
|
-
|
|
1427
|
+
skillifyLog(`Stop spawn failed: ${e?.message ?? e}`);
|
|
1391
1428
|
try {
|
|
1392
1429
|
releaseWorkerLock(state.projectKey);
|
|
1393
1430
|
} catch {
|
|
1394
1431
|
}
|
|
1395
1432
|
}
|
|
1396
1433
|
} catch (e) {
|
|
1397
|
-
|
|
1434
|
+
skillifyLog(`Stop trigger error: ${e?.message ?? e}`);
|
|
1398
1435
|
}
|
|
1399
1436
|
}
|
|
1400
1437
|
|
|
1401
1438
|
// dist/src/hooks/cursor/capture.js
|
|
1402
1439
|
var log4 = (msg) => log("cursor-capture", msg);
|
|
1403
1440
|
function resolveEmbedDaemonPath() {
|
|
1404
|
-
return
|
|
1441
|
+
return join14(dirname3(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
|
|
1405
1442
|
}
|
|
1406
1443
|
var CAPTURE = process.env.HIVEMIND_CAPTURE !== "false";
|
|
1407
1444
|
function resolveCwd(input) {
|
|
@@ -1489,7 +1526,7 @@ async function main() {
|
|
|
1489
1526
|
}
|
|
1490
1527
|
log4("capture ok \u2192 cloud");
|
|
1491
1528
|
maybeTriggerPeriodicSummary(sessionId, cwd, config);
|
|
1492
|
-
if (event === "afterAgentResponse" && process.env.HIVEMIND_WIKI_WORKER !== "1" && process.env.
|
|
1529
|
+
if (event === "afterAgentResponse" && process.env.HIVEMIND_WIKI_WORKER !== "1" && process.env.HIVEMIND_SKILLIFY_WORKER !== "1") {
|
|
1493
1530
|
tryStopCounterTrigger({
|
|
1494
1531
|
config,
|
|
1495
1532
|
cwd,
|
|
@@ -230,14 +230,14 @@ function bundleDirFromImportMeta(importMetaUrl) {
|
|
|
230
230
|
return dirname(fileURLToPath(importMetaUrl));
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
// dist/src/
|
|
233
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
234
234
|
import { spawn as spawn2 } from "node:child_process";
|
|
235
235
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
236
236
|
import { dirname as dirname2, join as join7 } from "node:path";
|
|
237
237
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
|
|
238
238
|
import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
|
|
239
239
|
|
|
240
|
-
// dist/src/
|
|
240
|
+
// dist/src/skillify/gate-runner.js
|
|
241
241
|
import { execFileSync } from "node:child_process";
|
|
242
242
|
import { existsSync as existsSync3 } from "node:fs";
|
|
243
243
|
import { homedir as homedir5 } from "node:os";
|
|
@@ -268,20 +268,20 @@ function findAgentBin(agent) {
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
// dist/src/
|
|
271
|
+
// dist/src/skillify/spawn-skillify-worker.js
|
|
272
272
|
var HOME2 = homedir6();
|
|
273
|
-
var
|
|
274
|
-
function
|
|
273
|
+
var SKILLIFY_LOG = join7(HOME2, ".claude", "hooks", "skillify.log");
|
|
274
|
+
function skillifyLog(msg) {
|
|
275
275
|
try {
|
|
276
|
-
mkdirSync4(dirname2(
|
|
277
|
-
appendFileSync3(
|
|
276
|
+
mkdirSync4(dirname2(SKILLIFY_LOG), { recursive: true });
|
|
277
|
+
appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
|
|
278
278
|
`);
|
|
279
279
|
} catch {
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
-
function
|
|
282
|
+
function spawnSkillifyWorker(opts) {
|
|
283
283
|
const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
|
|
284
|
-
const tmpDir = join7(tmpdir2(), `deeplake-
|
|
284
|
+
const tmpDir = join7(tmpdir2(), `deeplake-skillify-${projectKey}-${Date.now()}`);
|
|
285
285
|
mkdirSync4(tmpDir, { recursive: true, mode: 448 });
|
|
286
286
|
const gateBin = findAgentBin(agent);
|
|
287
287
|
const configFile = join7(tmpDir, "config.json");
|
|
@@ -307,40 +307,72 @@ function spawnSkilifyWorker(opts) {
|
|
|
307
307
|
hermesModel: process.env.HIVEMIND_HERMES_MODEL,
|
|
308
308
|
piProvider: process.env.HIVEMIND_PI_PROVIDER,
|
|
309
309
|
piModel: process.env.HIVEMIND_PI_MODEL,
|
|
310
|
-
|
|
310
|
+
skillifyLog: SKILLIFY_LOG,
|
|
311
311
|
currentSessionId
|
|
312
312
|
}), { mode: 384 });
|
|
313
313
|
try {
|
|
314
314
|
chmodSync(configFile, 384);
|
|
315
315
|
} catch {
|
|
316
316
|
}
|
|
317
|
-
|
|
318
|
-
const workerPath = join7(bundleDir, "
|
|
317
|
+
skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
|
|
318
|
+
const workerPath = join7(bundleDir, "skillify-worker.js");
|
|
319
319
|
spawn2("nohup", ["node", workerPath, configFile], {
|
|
320
320
|
detached: true,
|
|
321
321
|
stdio: ["ignore", "ignore", "ignore"]
|
|
322
322
|
}).unref();
|
|
323
|
-
|
|
323
|
+
skillifyLog(`${reason}: spawned skillify worker for ${projectKey}`);
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
// dist/src/
|
|
327
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, writeSync as writeSync2, mkdirSync as mkdirSync5, renameSync as
|
|
326
|
+
// dist/src/skillify/state.js
|
|
327
|
+
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";
|
|
328
328
|
import { execSync as execSync2 } from "node:child_process";
|
|
329
|
-
import { homedir as
|
|
329
|
+
import { homedir as homedir8 } from "node:os";
|
|
330
330
|
import { createHash } from "node:crypto";
|
|
331
|
-
import { join as
|
|
332
|
-
|
|
333
|
-
|
|
331
|
+
import { join as join9, basename } from "node:path";
|
|
332
|
+
|
|
333
|
+
// dist/src/skillify/legacy-migration.js
|
|
334
|
+
import { existsSync as existsSync4, renameSync as renameSync2 } from "node:fs";
|
|
335
|
+
import { homedir as homedir7 } from "node:os";
|
|
336
|
+
import { join as join8 } from "node:path";
|
|
337
|
+
var dlog2 = (msg) => log("skillify-migrate", msg);
|
|
338
|
+
var attempted = false;
|
|
339
|
+
function migrateLegacyStateDir() {
|
|
340
|
+
if (attempted)
|
|
341
|
+
return;
|
|
342
|
+
attempted = true;
|
|
343
|
+
const root = join8(homedir7(), ".deeplake", "state");
|
|
344
|
+
const legacy = join8(root, "skilify");
|
|
345
|
+
const current = join8(root, "skillify");
|
|
346
|
+
if (!existsSync4(legacy))
|
|
347
|
+
return;
|
|
348
|
+
if (existsSync4(current))
|
|
349
|
+
return;
|
|
350
|
+
try {
|
|
351
|
+
renameSync2(legacy, current);
|
|
352
|
+
dlog2(`migrated ${legacy} -> ${current}`);
|
|
353
|
+
} catch (err) {
|
|
354
|
+
const code = err.code;
|
|
355
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
356
|
+
dlog2(`migration failed (${code}); leaving legacy dir in place`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
throw err;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// dist/src/skillify/state.js
|
|
364
|
+
var dlog3 = (msg) => log("skillify-state", msg);
|
|
365
|
+
var STATE_DIR2 = join9(homedir8(), ".deeplake", "state", "skillify");
|
|
334
366
|
var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
|
|
335
367
|
var TRIGGER_THRESHOLD = (() => {
|
|
336
|
-
const n = Number(process.env.
|
|
368
|
+
const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
|
|
337
369
|
return Number.isInteger(n) && n > 0 ? n : 20;
|
|
338
370
|
})();
|
|
339
371
|
function statePath(projectKey) {
|
|
340
|
-
return
|
|
372
|
+
return join9(STATE_DIR2, `${projectKey}.json`);
|
|
341
373
|
}
|
|
342
374
|
function lockPath2(projectKey) {
|
|
343
|
-
return
|
|
375
|
+
return join9(STATE_DIR2, `${projectKey}.lock`);
|
|
344
376
|
}
|
|
345
377
|
function deriveProjectKey(cwd) {
|
|
346
378
|
const project = basename(cwd) || "unknown";
|
|
@@ -358,8 +390,9 @@ function deriveProjectKey(cwd) {
|
|
|
358
390
|
return { key, project };
|
|
359
391
|
}
|
|
360
392
|
function readState(projectKey) {
|
|
393
|
+
migrateLegacyStateDir();
|
|
361
394
|
const p = statePath(projectKey);
|
|
362
|
-
if (!
|
|
395
|
+
if (!existsSync5(p))
|
|
363
396
|
return null;
|
|
364
397
|
try {
|
|
365
398
|
return JSON.parse(readFileSync3(p, "utf-8"));
|
|
@@ -368,13 +401,15 @@ function readState(projectKey) {
|
|
|
368
401
|
}
|
|
369
402
|
}
|
|
370
403
|
function writeState(projectKey, state) {
|
|
404
|
+
migrateLegacyStateDir();
|
|
371
405
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
372
406
|
const p = statePath(projectKey);
|
|
373
407
|
const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
|
|
374
408
|
writeFileSync4(tmp, JSON.stringify(state, null, 2));
|
|
375
|
-
|
|
409
|
+
renameSync3(tmp, p);
|
|
376
410
|
}
|
|
377
411
|
function withRmwLock(projectKey, fn) {
|
|
412
|
+
migrateLegacyStateDir();
|
|
378
413
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
379
414
|
const rmw = lockPath2(projectKey) + ".rmw";
|
|
380
415
|
const deadline = Date.now() + 2e3;
|
|
@@ -386,11 +421,11 @@ function withRmwLock(projectKey, fn) {
|
|
|
386
421
|
if (e.code !== "EEXIST")
|
|
387
422
|
throw e;
|
|
388
423
|
if (Date.now() > deadline) {
|
|
389
|
-
|
|
424
|
+
dlog3(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
|
|
390
425
|
try {
|
|
391
426
|
unlinkSync2(rmw);
|
|
392
427
|
} catch (unlinkErr) {
|
|
393
|
-
|
|
428
|
+
dlog3(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
|
|
394
429
|
}
|
|
395
430
|
continue;
|
|
396
431
|
}
|
|
@@ -404,7 +439,7 @@ function withRmwLock(projectKey, fn) {
|
|
|
404
439
|
try {
|
|
405
440
|
unlinkSync2(rmw);
|
|
406
441
|
} catch (unlinkErr) {
|
|
407
|
-
|
|
442
|
+
dlog3(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
|
|
408
443
|
}
|
|
409
444
|
}
|
|
410
445
|
}
|
|
@@ -417,20 +452,21 @@ function resetCounter(projectKey) {
|
|
|
417
452
|
});
|
|
418
453
|
}
|
|
419
454
|
function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
|
|
455
|
+
migrateLegacyStateDir();
|
|
420
456
|
mkdirSync5(STATE_DIR2, { recursive: true });
|
|
421
457
|
const p = lockPath2(projectKey);
|
|
422
|
-
if (
|
|
458
|
+
if (existsSync5(p)) {
|
|
423
459
|
try {
|
|
424
460
|
const ageMs = Date.now() - parseInt(readFileSync3(p, "utf-8"), 10);
|
|
425
461
|
if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
|
|
426
462
|
return false;
|
|
427
463
|
} catch (readErr) {
|
|
428
|
-
|
|
464
|
+
dlog3(`worker lock unreadable for ${projectKey}, treating as stale: ${readErr.message}`);
|
|
429
465
|
}
|
|
430
466
|
try {
|
|
431
467
|
unlinkSync2(p);
|
|
432
468
|
} catch (unlinkErr) {
|
|
433
|
-
|
|
469
|
+
dlog3(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
|
|
434
470
|
return false;
|
|
435
471
|
}
|
|
436
472
|
}
|
|
@@ -454,15 +490,16 @@ function releaseWorkerLock(projectKey) {
|
|
|
454
490
|
}
|
|
455
491
|
}
|
|
456
492
|
|
|
457
|
-
// dist/src/
|
|
458
|
-
import { existsSync as
|
|
459
|
-
import { homedir as
|
|
460
|
-
import { join as
|
|
461
|
-
var STATE_DIR3 =
|
|
462
|
-
var CONFIG_PATH =
|
|
493
|
+
// dist/src/skillify/scope-config.js
|
|
494
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
495
|
+
import { homedir as homedir9 } from "node:os";
|
|
496
|
+
import { join as join10 } from "node:path";
|
|
497
|
+
var STATE_DIR3 = join10(homedir9(), ".deeplake", "state", "skillify");
|
|
498
|
+
var CONFIG_PATH = join10(STATE_DIR3, "config.json");
|
|
463
499
|
var DEFAULT = { scope: "me", team: [], install: "project" };
|
|
464
500
|
function loadScopeConfig() {
|
|
465
|
-
|
|
501
|
+
migrateLegacyStateDir();
|
|
502
|
+
if (!existsSync6(CONFIG_PATH))
|
|
466
503
|
return DEFAULT;
|
|
467
504
|
try {
|
|
468
505
|
const raw = JSON.parse(readFileSync4(CONFIG_PATH, "utf-8"));
|
|
@@ -475,24 +512,24 @@ function loadScopeConfig() {
|
|
|
475
512
|
}
|
|
476
513
|
}
|
|
477
514
|
|
|
478
|
-
// dist/src/
|
|
515
|
+
// dist/src/skillify/triggers.js
|
|
479
516
|
function forceSessionEndTrigger(opts) {
|
|
480
|
-
if (process.env.
|
|
517
|
+
if (process.env.HIVEMIND_SKILLIFY_WORKER === "1")
|
|
481
518
|
return;
|
|
482
519
|
if (!opts.cwd)
|
|
483
520
|
return;
|
|
484
521
|
try {
|
|
485
522
|
const { key: projectKey, project } = deriveProjectKey(opts.cwd);
|
|
486
523
|
if (!tryAcquireWorkerLock(projectKey)) {
|
|
487
|
-
|
|
524
|
+
skillifyLog(`SessionEnd: skillify worker already running for ${projectKey}, skipping`);
|
|
488
525
|
return;
|
|
489
526
|
}
|
|
490
527
|
if (readState(projectKey)) {
|
|
491
528
|
resetCounter(projectKey);
|
|
492
529
|
}
|
|
493
|
-
|
|
530
|
+
skillifyLog(`SessionEnd: spawning skillify worker for project=${project} agent=${opts.agent}`);
|
|
494
531
|
try {
|
|
495
|
-
|
|
532
|
+
spawnSkillifyWorker({
|
|
496
533
|
config: opts.config,
|
|
497
534
|
cwd: opts.cwd,
|
|
498
535
|
projectKey,
|
|
@@ -504,14 +541,14 @@ function forceSessionEndTrigger(opts) {
|
|
|
504
541
|
reason: "SessionEnd"
|
|
505
542
|
});
|
|
506
543
|
} catch (e) {
|
|
507
|
-
|
|
544
|
+
skillifyLog(`SessionEnd spawn failed: ${e?.message ?? e}`);
|
|
508
545
|
try {
|
|
509
546
|
releaseWorkerLock(projectKey);
|
|
510
547
|
} catch {
|
|
511
548
|
}
|
|
512
549
|
}
|
|
513
550
|
} catch (e) {
|
|
514
|
-
|
|
551
|
+
skillifyLog(`SessionEnd trigger error: ${e?.message ?? e}`);
|
|
515
552
|
}
|
|
516
553
|
}
|
|
517
554
|
|
|
@@ -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) => {
|