@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
|
@@ -670,12 +670,12 @@ async function autoUpdate(creds, opts) {
|
|
|
670
670
|
log3(`agent=${opts.agent} dispatched (pid=${pid ?? "?"}) (${Date.now() - t0}ms total)`);
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
-
// dist/src/
|
|
674
|
-
import { existsSync as
|
|
675
|
-
import { homedir as
|
|
676
|
-
import { dirname as dirname3, join as
|
|
673
|
+
// dist/src/skillify/pull.js
|
|
674
|
+
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";
|
|
675
|
+
import { homedir as homedir8 } from "node:os";
|
|
676
|
+
import { dirname as dirname3, join as join11 } from "node:path";
|
|
677
677
|
|
|
678
|
-
// dist/src/
|
|
678
|
+
// dist/src/skillify/skill-writer.js
|
|
679
679
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
680
680
|
import { homedir as homedir4 } from "node:os";
|
|
681
681
|
import { join as join7 } from "node:path";
|
|
@@ -736,18 +736,51 @@ function parseFrontmatter(text) {
|
|
|
736
736
|
return { fm, body };
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
-
// dist/src/
|
|
740
|
-
import { existsSync as
|
|
739
|
+
// dist/src/skillify/manifest.js
|
|
740
|
+
import { existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
741
|
+
import { homedir as homedir6 } from "node:os";
|
|
742
|
+
import { dirname as dirname2, join as join9 } from "node:path";
|
|
743
|
+
|
|
744
|
+
// dist/src/skillify/legacy-migration.js
|
|
745
|
+
import { existsSync as existsSync5, renameSync } from "node:fs";
|
|
741
746
|
import { homedir as homedir5 } from "node:os";
|
|
742
|
-
import {
|
|
747
|
+
import { join as join8 } from "node:path";
|
|
748
|
+
var dlog = (msg) => log("skillify-migrate", msg);
|
|
749
|
+
var attempted = false;
|
|
750
|
+
function migrateLegacyStateDir() {
|
|
751
|
+
if (attempted)
|
|
752
|
+
return;
|
|
753
|
+
attempted = true;
|
|
754
|
+
const root = join8(homedir5(), ".deeplake", "state");
|
|
755
|
+
const legacy = join8(root, "skilify");
|
|
756
|
+
const current = join8(root, "skillify");
|
|
757
|
+
if (!existsSync5(legacy))
|
|
758
|
+
return;
|
|
759
|
+
if (existsSync5(current))
|
|
760
|
+
return;
|
|
761
|
+
try {
|
|
762
|
+
renameSync(legacy, current);
|
|
763
|
+
dlog(`migrated ${legacy} -> ${current}`);
|
|
764
|
+
} catch (err) {
|
|
765
|
+
const code = err.code;
|
|
766
|
+
if (code === "EXDEV" || code === "EPERM") {
|
|
767
|
+
dlog(`migration failed (${code}); leaving legacy dir in place`);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
throw err;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// dist/src/skillify/manifest.js
|
|
743
775
|
function emptyManifest() {
|
|
744
776
|
return { version: 1, entries: [] };
|
|
745
777
|
}
|
|
746
778
|
function manifestPath() {
|
|
747
|
-
return
|
|
779
|
+
return join9(homedir6(), ".deeplake", "state", "skillify", "pulled.json");
|
|
748
780
|
}
|
|
749
781
|
function loadManifest(path = manifestPath()) {
|
|
750
|
-
|
|
782
|
+
migrateLegacyStateDir();
|
|
783
|
+
if (!existsSync6(path))
|
|
751
784
|
return emptyManifest();
|
|
752
785
|
let raw;
|
|
753
786
|
try {
|
|
@@ -797,10 +830,11 @@ function loadManifest(path = manifestPath()) {
|
|
|
797
830
|
}
|
|
798
831
|
}
|
|
799
832
|
function saveManifest(m, path = manifestPath()) {
|
|
833
|
+
migrateLegacyStateDir();
|
|
800
834
|
mkdirSync4(dirname2(path), { recursive: true });
|
|
801
835
|
const tmp = `${path}.tmp`;
|
|
802
836
|
writeFileSync4(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
803
|
-
|
|
837
|
+
renameSync2(tmp, path);
|
|
804
838
|
}
|
|
805
839
|
function recordPull(entry, path = manifestPath()) {
|
|
806
840
|
const m = loadManifest(path);
|
|
@@ -835,7 +869,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
835
869
|
const live = [];
|
|
836
870
|
let pruned = 0;
|
|
837
871
|
for (const e of m.entries) {
|
|
838
|
-
if (
|
|
872
|
+
if (existsSync6(join9(e.installRoot, e.dirName))) {
|
|
839
873
|
live.push(e);
|
|
840
874
|
continue;
|
|
841
875
|
}
|
|
@@ -847,31 +881,31 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
847
881
|
return pruned;
|
|
848
882
|
}
|
|
849
883
|
|
|
850
|
-
// dist/src/
|
|
851
|
-
import { existsSync as
|
|
852
|
-
import { homedir as
|
|
853
|
-
import { join as
|
|
884
|
+
// dist/src/skillify/agent-roots.js
|
|
885
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
886
|
+
import { homedir as homedir7 } from "node:os";
|
|
887
|
+
import { join as join10 } from "node:path";
|
|
854
888
|
function resolveDetected(home) {
|
|
855
889
|
const out = [];
|
|
856
|
-
const codexInstalled =
|
|
857
|
-
const piInstalled =
|
|
858
|
-
const hermesInstalled =
|
|
890
|
+
const codexInstalled = existsSync7(join10(home, ".codex"));
|
|
891
|
+
const piInstalled = existsSync7(join10(home, ".pi", "agent"));
|
|
892
|
+
const hermesInstalled = existsSync7(join10(home, ".hermes"));
|
|
859
893
|
if (codexInstalled || piInstalled) {
|
|
860
|
-
out.push(
|
|
894
|
+
out.push(join10(home, ".agents", "skills"));
|
|
861
895
|
}
|
|
862
896
|
if (hermesInstalled) {
|
|
863
|
-
out.push(
|
|
897
|
+
out.push(join10(home, ".hermes", "skills"));
|
|
864
898
|
}
|
|
865
899
|
if (piInstalled) {
|
|
866
|
-
out.push(
|
|
900
|
+
out.push(join10(home, ".pi", "agent", "skills"));
|
|
867
901
|
}
|
|
868
902
|
return out;
|
|
869
903
|
}
|
|
870
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
904
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir7()) {
|
|
871
905
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
872
906
|
}
|
|
873
907
|
|
|
874
|
-
// dist/src/
|
|
908
|
+
// dist/src/skillify/pull.js
|
|
875
909
|
function assertValidAuthor(author) {
|
|
876
910
|
if (!author)
|
|
877
911
|
throw new Error("author is empty");
|
|
@@ -903,15 +937,15 @@ function isMissingTableError(message) {
|
|
|
903
937
|
}
|
|
904
938
|
function resolvePullDestination(install, cwd) {
|
|
905
939
|
if (install === "global")
|
|
906
|
-
return
|
|
940
|
+
return join11(homedir8(), ".claude", "skills");
|
|
907
941
|
if (!cwd)
|
|
908
942
|
throw new Error("install=project requires a cwd");
|
|
909
|
-
return
|
|
943
|
+
return join11(cwd, ".claude", "skills");
|
|
910
944
|
}
|
|
911
945
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
912
946
|
const out = [];
|
|
913
947
|
for (const root of agentRoots) {
|
|
914
|
-
const link =
|
|
948
|
+
const link = join11(root, dirName);
|
|
915
949
|
let existing;
|
|
916
950
|
try {
|
|
917
951
|
existing = lstatSync2(link);
|
|
@@ -954,8 +988,8 @@ function backfillSymlinks(installRoot) {
|
|
|
954
988
|
return;
|
|
955
989
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
956
990
|
for (const entry of entries) {
|
|
957
|
-
const canonical =
|
|
958
|
-
if (!
|
|
991
|
+
const canonical = join11(entry.installRoot, entry.dirName);
|
|
992
|
+
if (!existsSync8(canonical))
|
|
959
993
|
continue;
|
|
960
994
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
961
995
|
if (sameSorted(fresh, entry.symlinks))
|
|
@@ -1040,7 +1074,7 @@ function renderFrontmatter(fm) {
|
|
|
1040
1074
|
return lines.join("\n");
|
|
1041
1075
|
}
|
|
1042
1076
|
function readLocalVersion(path) {
|
|
1043
|
-
if (!
|
|
1077
|
+
if (!existsSync8(path))
|
|
1044
1078
|
return null;
|
|
1045
1079
|
try {
|
|
1046
1080
|
const text = readFileSync7(path, "utf-8");
|
|
@@ -1129,8 +1163,8 @@ async function runPull(opts) {
|
|
|
1129
1163
|
summary.skipped++;
|
|
1130
1164
|
continue;
|
|
1131
1165
|
}
|
|
1132
|
-
const skillDir =
|
|
1133
|
-
const skillFile =
|
|
1166
|
+
const skillDir = join11(root, dirName);
|
|
1167
|
+
const skillFile = join11(skillDir, "SKILL.md");
|
|
1134
1168
|
const remoteVersion = Number(row.version ?? 1);
|
|
1135
1169
|
const localVersion = readLocalVersion(skillFile);
|
|
1136
1170
|
const action = decideAction({
|
|
@@ -1142,9 +1176,9 @@ async function runPull(opts) {
|
|
|
1142
1176
|
let manifestError;
|
|
1143
1177
|
if (action === "wrote") {
|
|
1144
1178
|
mkdirSync5(skillDir, { recursive: true });
|
|
1145
|
-
if (
|
|
1179
|
+
if (existsSync8(skillFile)) {
|
|
1146
1180
|
try {
|
|
1147
|
-
|
|
1181
|
+
renameSync3(skillFile, `${skillFile}.bak`);
|
|
1148
1182
|
} catch {
|
|
1149
1183
|
}
|
|
1150
1184
|
}
|
|
@@ -1189,8 +1223,8 @@ async function runPull(opts) {
|
|
|
1189
1223
|
return summary;
|
|
1190
1224
|
}
|
|
1191
1225
|
|
|
1192
|
-
// dist/src/
|
|
1193
|
-
var log4 = (msg) => log("
|
|
1226
|
+
// dist/src/skillify/auto-pull.js
|
|
1227
|
+
var log4 = (msg) => log("skillify-autopull", msg);
|
|
1194
1228
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1195
1229
|
function withTimeout(p, ms) {
|
|
1196
1230
|
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
|
async function createPlaceholder(api, table, sessionId, cwd, userName, orgName, workspaceId) {
|
|
1285
1319
|
const summaryPath = `/summaries/${userName}/${sessionId}.md`;
|
|
1286
1320
|
const existing = await api.query(`SELECT path FROM "${table}" WHERE path = '${sqlStr(summaryPath)}' LIMIT 1`);
|
|
@@ -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) {
|