@deeplake/hivemind 0.7.17 → 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 +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
|
@@ -671,12 +671,12 @@ async function autoUpdate(creds, opts) {
|
|
|
671
671
|
log3(`agent=${opts.agent} dispatched (pid=${pid ?? "?"}) (${Date.now() - t0}ms total)`);
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
-
// dist/src/
|
|
675
|
-
import { existsSync as
|
|
676
|
-
import { homedir as
|
|
677
|
-
import { dirname as dirname3, join as
|
|
674
|
+
// dist/src/skillify/pull.js
|
|
675
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync3, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
676
|
+
import { homedir as homedir8 } from "node:os";
|
|
677
|
+
import { dirname as dirname3, join as join11 } from "node:path";
|
|
678
678
|
|
|
679
|
-
// dist/src/
|
|
679
|
+
// dist/src/skillify/skill-writer.js
|
|
680
680
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
681
681
|
import { homedir as homedir4 } from "node:os";
|
|
682
682
|
import { join as join7 } from "node:path";
|
|
@@ -737,18 +737,51 @@ function parseFrontmatter(text) {
|
|
|
737
737
|
return { fm, body };
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
-
// dist/src/
|
|
741
|
-
import { existsSync as
|
|
740
|
+
// dist/src/skillify/manifest.js
|
|
741
|
+
import { existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
742
|
+
import { homedir as homedir6 } from "node:os";
|
|
743
|
+
import { dirname as dirname2, join as join9 } from "node:path";
|
|
744
|
+
|
|
745
|
+
// dist/src/skillify/legacy-migration.js
|
|
746
|
+
import { existsSync as existsSync5, renameSync } from "node:fs";
|
|
742
747
|
import { homedir as homedir5 } from "node:os";
|
|
743
|
-
import {
|
|
748
|
+
import { join as join8 } from "node:path";
|
|
749
|
+
var dlog = (msg) => log("skillify-migrate", msg);
|
|
750
|
+
var attempted = false;
|
|
751
|
+
function migrateLegacyStateDir() {
|
|
752
|
+
if (attempted)
|
|
753
|
+
return;
|
|
754
|
+
attempted = true;
|
|
755
|
+
const root = join8(homedir5(), ".deeplake", "state");
|
|
756
|
+
const legacy = join8(root, "skilify");
|
|
757
|
+
const current = join8(root, "skillify");
|
|
758
|
+
if (!existsSync5(legacy))
|
|
759
|
+
return;
|
|
760
|
+
if (existsSync5(current))
|
|
761
|
+
return;
|
|
762
|
+
try {
|
|
763
|
+
renameSync(legacy, current);
|
|
764
|
+
dlog(`migrated ${legacy} -> ${current}`);
|
|
765
|
+
} catch (err) {
|
|
766
|
+
const code = err.code;
|
|
767
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
768
|
+
dlog(`migration failed (${code}); leaving legacy dir in place`);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
throw err;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// dist/src/skillify/manifest.js
|
|
744
776
|
function emptyManifest() {
|
|
745
777
|
return { version: 1, entries: [] };
|
|
746
778
|
}
|
|
747
779
|
function manifestPath() {
|
|
748
|
-
return
|
|
780
|
+
return join9(homedir6(), ".deeplake", "state", "skillify", "pulled.json");
|
|
749
781
|
}
|
|
750
782
|
function loadManifest(path = manifestPath()) {
|
|
751
|
-
|
|
783
|
+
migrateLegacyStateDir();
|
|
784
|
+
if (!existsSync6(path))
|
|
752
785
|
return emptyManifest();
|
|
753
786
|
let raw;
|
|
754
787
|
try {
|
|
@@ -798,10 +831,11 @@ function loadManifest(path = manifestPath()) {
|
|
|
798
831
|
}
|
|
799
832
|
}
|
|
800
833
|
function saveManifest(m, path = manifestPath()) {
|
|
834
|
+
migrateLegacyStateDir();
|
|
801
835
|
mkdirSync4(dirname2(path), { recursive: true });
|
|
802
836
|
const tmp = `${path}.tmp`;
|
|
803
837
|
writeFileSync4(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
804
|
-
|
|
838
|
+
renameSync2(tmp, path);
|
|
805
839
|
}
|
|
806
840
|
function recordPull(entry, path = manifestPath()) {
|
|
807
841
|
const m = loadManifest(path);
|
|
@@ -836,7 +870,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
836
870
|
const live = [];
|
|
837
871
|
let pruned = 0;
|
|
838
872
|
for (const e of m.entries) {
|
|
839
|
-
if (
|
|
873
|
+
if (existsSync6(join9(e.installRoot, e.dirName))) {
|
|
840
874
|
live.push(e);
|
|
841
875
|
continue;
|
|
842
876
|
}
|
|
@@ -848,31 +882,31 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
848
882
|
return pruned;
|
|
849
883
|
}
|
|
850
884
|
|
|
851
|
-
// dist/src/
|
|
852
|
-
import { existsSync as
|
|
853
|
-
import { homedir as
|
|
854
|
-
import { join as
|
|
885
|
+
// dist/src/skillify/agent-roots.js
|
|
886
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
887
|
+
import { homedir as homedir7 } from "node:os";
|
|
888
|
+
import { join as join10 } from "node:path";
|
|
855
889
|
function resolveDetected(home) {
|
|
856
890
|
const out = [];
|
|
857
|
-
const codexInstalled =
|
|
858
|
-
const piInstalled =
|
|
859
|
-
const hermesInstalled =
|
|
891
|
+
const codexInstalled = existsSync7(join10(home, ".codex"));
|
|
892
|
+
const piInstalled = existsSync7(join10(home, ".pi", "agent"));
|
|
893
|
+
const hermesInstalled = existsSync7(join10(home, ".hermes"));
|
|
860
894
|
if (codexInstalled || piInstalled) {
|
|
861
|
-
out.push(
|
|
895
|
+
out.push(join10(home, ".agents", "skills"));
|
|
862
896
|
}
|
|
863
897
|
if (hermesInstalled) {
|
|
864
|
-
out.push(
|
|
898
|
+
out.push(join10(home, ".hermes", "skills"));
|
|
865
899
|
}
|
|
866
900
|
if (piInstalled) {
|
|
867
|
-
out.push(
|
|
901
|
+
out.push(join10(home, ".pi", "agent", "skills"));
|
|
868
902
|
}
|
|
869
903
|
return out;
|
|
870
904
|
}
|
|
871
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
905
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir7()) {
|
|
872
906
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
873
907
|
}
|
|
874
908
|
|
|
875
|
-
// dist/src/
|
|
909
|
+
// dist/src/skillify/pull.js
|
|
876
910
|
function assertValidAuthor(author) {
|
|
877
911
|
if (!author)
|
|
878
912
|
throw new Error("author is empty");
|
|
@@ -904,15 +938,15 @@ function isMissingTableError(message) {
|
|
|
904
938
|
}
|
|
905
939
|
function resolvePullDestination(install, cwd) {
|
|
906
940
|
if (install === "global")
|
|
907
|
-
return
|
|
941
|
+
return join11(homedir8(), ".claude", "skills");
|
|
908
942
|
if (!cwd)
|
|
909
943
|
throw new Error("install=project requires a cwd");
|
|
910
|
-
return
|
|
944
|
+
return join11(cwd, ".claude", "skills");
|
|
911
945
|
}
|
|
912
946
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
913
947
|
const out = [];
|
|
914
948
|
for (const root of agentRoots) {
|
|
915
|
-
const link =
|
|
949
|
+
const link = join11(root, dirName);
|
|
916
950
|
let existing;
|
|
917
951
|
try {
|
|
918
952
|
existing = lstatSync2(link);
|
|
@@ -955,8 +989,8 @@ function backfillSymlinks(installRoot) {
|
|
|
955
989
|
return;
|
|
956
990
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
957
991
|
for (const entry of entries) {
|
|
958
|
-
const canonical =
|
|
959
|
-
if (!
|
|
992
|
+
const canonical = join11(entry.installRoot, entry.dirName);
|
|
993
|
+
if (!existsSync8(canonical))
|
|
960
994
|
continue;
|
|
961
995
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
962
996
|
if (sameSorted(fresh, entry.symlinks))
|
|
@@ -1041,7 +1075,7 @@ function renderFrontmatter(fm) {
|
|
|
1041
1075
|
return lines.join("\n");
|
|
1042
1076
|
}
|
|
1043
1077
|
function readLocalVersion(path) {
|
|
1044
|
-
if (!
|
|
1078
|
+
if (!existsSync8(path))
|
|
1045
1079
|
return null;
|
|
1046
1080
|
try {
|
|
1047
1081
|
const text = readFileSync7(path, "utf-8");
|
|
@@ -1130,8 +1164,8 @@ async function runPull(opts) {
|
|
|
1130
1164
|
summary.skipped++;
|
|
1131
1165
|
continue;
|
|
1132
1166
|
}
|
|
1133
|
-
const skillDir =
|
|
1134
|
-
const skillFile =
|
|
1167
|
+
const skillDir = join11(root, dirName);
|
|
1168
|
+
const skillFile = join11(skillDir, "SKILL.md");
|
|
1135
1169
|
const remoteVersion = Number(row.version ?? 1);
|
|
1136
1170
|
const localVersion = readLocalVersion(skillFile);
|
|
1137
1171
|
const action = decideAction({
|
|
@@ -1143,9 +1177,9 @@ async function runPull(opts) {
|
|
|
1143
1177
|
let manifestError;
|
|
1144
1178
|
if (action === "wrote") {
|
|
1145
1179
|
mkdirSync5(skillDir, { recursive: true });
|
|
1146
|
-
if (
|
|
1180
|
+
if (existsSync8(skillFile)) {
|
|
1147
1181
|
try {
|
|
1148
|
-
|
|
1182
|
+
renameSync3(skillFile, `${skillFile}.bak`);
|
|
1149
1183
|
} catch {
|
|
1150
1184
|
}
|
|
1151
1185
|
}
|
|
@@ -1190,8 +1224,8 @@ async function runPull(opts) {
|
|
|
1190
1224
|
return summary;
|
|
1191
1225
|
}
|
|
1192
1226
|
|
|
1193
|
-
// dist/src/
|
|
1194
|
-
var log4 = (msg) => log("
|
|
1227
|
+
// dist/src/skillify/auto-pull.js
|
|
1228
|
+
var log4 = (msg) => log("skillify-autopull", msg);
|
|
1195
1229
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1196
1230
|
function withTimeout(p, ms) {
|
|
1197
1231
|
let timer = null;
|
|
@@ -1264,23 +1298,23 @@ Organization management \u2014 each argument is SEPARATE (do NOT quote subcomman
|
|
|
1264
1298
|
- hivemind members \u2014 list members
|
|
1265
1299
|
- hivemind remove <user-id> \u2014 remove member
|
|
1266
1300
|
|
|
1267
|
-
SKILLS (
|
|
1268
|
-
- hivemind
|
|
1269
|
-
- hivemind
|
|
1270
|
-
- hivemind
|
|
1271
|
-
- hivemind
|
|
1272
|
-
- hivemind
|
|
1273
|
-
- hivemind
|
|
1274
|
-
- hivemind
|
|
1275
|
-
- hivemind
|
|
1276
|
-
- hivemind
|
|
1277
|
-
- hivemind
|
|
1278
|
-
- hivemind
|
|
1279
|
-
- hivemind
|
|
1280
|
-
- hivemind
|
|
1281
|
-
- hivemind
|
|
1282
|
-
- hivemind
|
|
1283
|
-
- hivemind
|
|
1301
|
+
SKILLS (skillify) \u2014 mine + share reusable skills across the org:
|
|
1302
|
+
- hivemind skillify \u2014 show scope/team/install + per-project state
|
|
1303
|
+
- hivemind skillify pull \u2014 sync project skills from the org table
|
|
1304
|
+
- hivemind skillify pull --user <email> \u2014 only that author's skills
|
|
1305
|
+
- hivemind skillify pull --users a,b,c \u2014 multiple authors (CSV)
|
|
1306
|
+
- hivemind skillify pull --all-users \u2014 explicit "no author filter"
|
|
1307
|
+
- hivemind skillify pull --to project|global \u2014 install location
|
|
1308
|
+
- hivemind skillify pull --dry-run \u2014 preview only
|
|
1309
|
+
- hivemind skillify pull --force \u2014 overwrite local (creates .bak)
|
|
1310
|
+
- hivemind skillify pull <skill-name> \u2014 pull only that skill (combines with --user)
|
|
1311
|
+
- hivemind skillify unpull \u2014 remove every skill previously installed by pull
|
|
1312
|
+
- hivemind skillify unpull --user <email> \u2014 remove only that author's pulls
|
|
1313
|
+
- hivemind skillify unpull --not-mine \u2014 remove all pulls except your own
|
|
1314
|
+
- hivemind skillify unpull --dry-run \u2014 preview without touching disk
|
|
1315
|
+
- hivemind skillify scope <me|team|org> \u2014 sharing scope for new skills
|
|
1316
|
+
- hivemind skillify install <project|global> \u2014 default install location
|
|
1317
|
+
- hivemind skillify team add|remove|list <name> \u2014 manage team list`;
|
|
1284
1318
|
function resolveSessionId(input) {
|
|
1285
1319
|
return input.session_id ?? input.conversation_id ?? `cursor-${Date.now()}`;
|
|
1286
1320
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// dist/src/
|
|
4
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as
|
|
5
|
-
import { join as
|
|
3
|
+
// dist/src/skillify/skillify-worker.js
|
|
4
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync5, appendFileSync as appendFileSync2, rmSync } from "node:fs";
|
|
5
|
+
import { join as join6 } from "node:path";
|
|
6
6
|
|
|
7
7
|
// dist/src/utils/debug.js
|
|
8
8
|
import { appendFileSync } from "node:fs";
|
|
@@ -29,7 +29,7 @@ function deeplakeClientHeader() {
|
|
|
29
29
|
return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// dist/src/
|
|
32
|
+
// dist/src/skillify/extractors/index.js
|
|
33
33
|
function extractPairs(rows) {
|
|
34
34
|
const pairs = [];
|
|
35
35
|
let pendingPrompt = null;
|
|
@@ -60,7 +60,7 @@ function extractPairs(rows) {
|
|
|
60
60
|
return pairs;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// dist/src/
|
|
63
|
+
// dist/src/skillify/skill-writer.js
|
|
64
64
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
65
65
|
import { homedir as homedir2 } from "node:os";
|
|
66
66
|
import { join as join2 } from "node:path";
|
|
@@ -216,7 +216,7 @@ function resolveSkillsRoot(install, cwd) {
|
|
|
216
216
|
return join2(cwd, ".claude", "skills");
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
// dist/src/
|
|
219
|
+
// dist/src/skillify/skills-table.js
|
|
220
220
|
import { randomUUID } from "node:crypto";
|
|
221
221
|
|
|
222
222
|
// dist/src/utils/sql.js
|
|
@@ -227,7 +227,7 @@ function sqlIdent(name) {
|
|
|
227
227
|
return name;
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
// dist/src/
|
|
230
|
+
// dist/src/skillify/skills-table.js
|
|
231
231
|
function createSkillsTableSql(tableName) {
|
|
232
232
|
const safe = sqlIdent(tableName);
|
|
233
233
|
return `CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', project TEXT NOT NULL DEFAULT '', project_key TEXT NOT NULL DEFAULT '', local_path TEXT NOT NULL DEFAULT '', install TEXT NOT NULL DEFAULT 'project', source_sessions TEXT NOT NULL DEFAULT '[]', source_agent TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL DEFAULT 'me', author TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', trigger_text TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '', version BIGINT NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT '', updated_at TEXT NOT NULL DEFAULT '') USING deeplake`;
|
|
@@ -256,7 +256,7 @@ async function insertSkillRow(args) {
|
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
// dist/src/
|
|
259
|
+
// dist/src/skillify/gate-parser.js
|
|
260
260
|
function extractJsonBlock(s) {
|
|
261
261
|
const trimmed = s.trim();
|
|
262
262
|
if (!trimmed)
|
|
@@ -294,7 +294,7 @@ function parseVerdict(raw) {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
// dist/src/
|
|
297
|
+
// dist/src/skillify/gate-runner.js
|
|
298
298
|
import { execFileSync } from "node:child_process";
|
|
299
299
|
import { existsSync as existsSync2 } from "node:fs";
|
|
300
300
|
import { homedir as homedir3 } from "node:os";
|
|
@@ -403,28 +403,61 @@ function runGate(opts) {
|
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
-
// dist/src/
|
|
407
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, writeSync, mkdirSync as mkdirSync2, renameSync, existsSync as
|
|
406
|
+
// dist/src/skillify/state.js
|
|
407
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, writeSync, mkdirSync as mkdirSync2, renameSync as renameSync2, existsSync as existsSync4, unlinkSync, openSync, closeSync } from "node:fs";
|
|
408
408
|
import { execSync } from "node:child_process";
|
|
409
|
-
import { homedir as
|
|
409
|
+
import { homedir as homedir5 } from "node:os";
|
|
410
410
|
import { createHash } from "node:crypto";
|
|
411
|
-
import { join as
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
import { join as join5, basename } from "node:path";
|
|
412
|
+
|
|
413
|
+
// dist/src/skillify/legacy-migration.js
|
|
414
|
+
import { existsSync as existsSync3, renameSync } from "node:fs";
|
|
415
|
+
import { homedir as homedir4 } from "node:os";
|
|
416
|
+
import { join as join4 } from "node:path";
|
|
417
|
+
var dlog = (msg) => log("skillify-migrate", msg);
|
|
418
|
+
var attempted = false;
|
|
419
|
+
function migrateLegacyStateDir() {
|
|
420
|
+
if (attempted)
|
|
421
|
+
return;
|
|
422
|
+
attempted = true;
|
|
423
|
+
const root = join4(homedir4(), ".deeplake", "state");
|
|
424
|
+
const legacy = join4(root, "skilify");
|
|
425
|
+
const current = join4(root, "skillify");
|
|
426
|
+
if (!existsSync3(legacy))
|
|
427
|
+
return;
|
|
428
|
+
if (existsSync3(current))
|
|
429
|
+
return;
|
|
430
|
+
try {
|
|
431
|
+
renameSync(legacy, current);
|
|
432
|
+
dlog(`migrated ${legacy} -> ${current}`);
|
|
433
|
+
} catch (err) {
|
|
434
|
+
const code = err.code;
|
|
435
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
436
|
+
dlog(`migration failed (${code}); leaving legacy dir in place`);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
throw err;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// dist/src/skillify/state.js
|
|
444
|
+
var dlog2 = (msg) => log("skillify-state", msg);
|
|
445
|
+
var STATE_DIR = join5(homedir5(), ".deeplake", "state", "skillify");
|
|
414
446
|
var YIELD_BUF = new Int32Array(new SharedArrayBuffer(4));
|
|
415
447
|
var TRIGGER_THRESHOLD = (() => {
|
|
416
|
-
const n = Number(process.env.
|
|
448
|
+
const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
|
|
417
449
|
return Number.isInteger(n) && n > 0 ? n : 20;
|
|
418
450
|
})();
|
|
419
451
|
function statePath(projectKey) {
|
|
420
|
-
return
|
|
452
|
+
return join5(STATE_DIR, `${projectKey}.json`);
|
|
421
453
|
}
|
|
422
454
|
function lockPath(projectKey) {
|
|
423
|
-
return
|
|
455
|
+
return join5(STATE_DIR, `${projectKey}.lock`);
|
|
424
456
|
}
|
|
425
457
|
function readState(projectKey) {
|
|
458
|
+
migrateLegacyStateDir();
|
|
426
459
|
const p = statePath(projectKey);
|
|
427
|
-
if (!
|
|
460
|
+
if (!existsSync4(p))
|
|
428
461
|
return null;
|
|
429
462
|
try {
|
|
430
463
|
return JSON.parse(readFileSync2(p, "utf-8"));
|
|
@@ -433,13 +466,15 @@ function readState(projectKey) {
|
|
|
433
466
|
}
|
|
434
467
|
}
|
|
435
468
|
function writeState(projectKey, state) {
|
|
469
|
+
migrateLegacyStateDir();
|
|
436
470
|
mkdirSync2(STATE_DIR, { recursive: true });
|
|
437
471
|
const p = statePath(projectKey);
|
|
438
472
|
const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
|
|
439
473
|
writeFileSync2(tmp, JSON.stringify(state, null, 2));
|
|
440
|
-
|
|
474
|
+
renameSync2(tmp, p);
|
|
441
475
|
}
|
|
442
476
|
function withRmwLock(projectKey, fn) {
|
|
477
|
+
migrateLegacyStateDir();
|
|
443
478
|
mkdirSync2(STATE_DIR, { recursive: true });
|
|
444
479
|
const rmw = lockPath(projectKey) + ".rmw";
|
|
445
480
|
const deadline = Date.now() + 2e3;
|
|
@@ -451,11 +486,11 @@ function withRmwLock(projectKey, fn) {
|
|
|
451
486
|
if (e.code !== "EEXIST")
|
|
452
487
|
throw e;
|
|
453
488
|
if (Date.now() > deadline) {
|
|
454
|
-
|
|
489
|
+
dlog2(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
|
|
455
490
|
try {
|
|
456
491
|
unlinkSync(rmw);
|
|
457
492
|
} catch (unlinkErr) {
|
|
458
|
-
|
|
493
|
+
dlog2(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
|
|
459
494
|
}
|
|
460
495
|
continue;
|
|
461
496
|
}
|
|
@@ -469,7 +504,7 @@ function withRmwLock(projectKey, fn) {
|
|
|
469
504
|
try {
|
|
470
505
|
unlinkSync(rmw);
|
|
471
506
|
} catch (unlinkErr) {
|
|
472
|
-
|
|
507
|
+
dlog2(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
|
|
473
508
|
}
|
|
474
509
|
}
|
|
475
510
|
}
|
|
@@ -509,18 +544,18 @@ function releaseWorkerLock(projectKey) {
|
|
|
509
544
|
}
|
|
510
545
|
}
|
|
511
546
|
|
|
512
|
-
// dist/src/
|
|
547
|
+
// dist/src/skillify/skillify-worker.js
|
|
513
548
|
var cfg = JSON.parse(readFileSync3(process.argv[2], "utf-8"));
|
|
514
549
|
var tmpDir = cfg.tmpDir;
|
|
515
|
-
var verdictPath =
|
|
516
|
-
var promptPath =
|
|
550
|
+
var verdictPath = join6(tmpDir, "verdict.json");
|
|
551
|
+
var promptPath = join6(tmpDir, "prompt.txt");
|
|
517
552
|
var SESSIONS_TO_MINE = 10;
|
|
518
553
|
var PAIR_CHAR_CAP = 2e3;
|
|
519
554
|
var TOTAL_PAIRS_CHAR_CAP = 4e4;
|
|
520
555
|
var EXISTING_SKILLS_CHAR_CAP = 3e4;
|
|
521
556
|
function wlog(msg) {
|
|
522
557
|
try {
|
|
523
|
-
appendFileSync2(cfg.
|
|
558
|
+
appendFileSync2(cfg.skillifyLog, `[${utcTimestamp()}] skillify-worker(${cfg.projectKey}): ${msg}
|
|
524
559
|
`);
|
|
525
560
|
} catch {
|
|
526
561
|
}
|
|
@@ -715,7 +750,7 @@ function buildPrompt(pairs) {
|
|
|
715
750
|
].join("\n");
|
|
716
751
|
}
|
|
717
752
|
function readVerdict(stdout) {
|
|
718
|
-
if (
|
|
753
|
+
if (existsSync5(verdictPath)) {
|
|
719
754
|
try {
|
|
720
755
|
const text = readFileSync3(verdictPath, "utf-8");
|
|
721
756
|
const v2 = parseVerdict(text);
|
|
@@ -784,9 +819,9 @@ async function main() {
|
|
|
784
819
|
timeoutMs: 12e4
|
|
785
820
|
});
|
|
786
821
|
try {
|
|
787
|
-
writeFileSync3(
|
|
822
|
+
writeFileSync3(join6(tmpDir, "gate-stdout.txt"), gate.stdout);
|
|
788
823
|
if (gate.stderr)
|
|
789
|
-
writeFileSync3(
|
|
824
|
+
writeFileSync3(join6(tmpDir, "gate-stderr.txt"), gate.stderr);
|
|
790
825
|
} catch {
|
|
791
826
|
}
|
|
792
827
|
if (gate.errored) {
|