@deeplake/hivemind 0.7.16 → 0.7.17

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.
@@ -54,7 +54,7 @@ var init_index_marker_store = __esm({
54
54
 
55
55
  // dist/src/hooks/cursor/session-start.js
56
56
  import { fileURLToPath } from "node:url";
57
- import { dirname as dirname2 } from "node:path";
57
+ import { dirname as dirname4 } from "node:path";
58
58
 
59
59
  // dist/src/commands/auth.js
60
60
  import { execSync } from "node:child_process";
@@ -671,9 +671,581 @@ 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/skilify/pull.js
675
+ import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync2, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync3 } from "node:fs";
676
+ import { homedir as homedir7 } from "node:os";
677
+ import { dirname as dirname3, join as join10 } from "node:path";
678
+
679
+ // dist/src/skilify/skill-writer.js
680
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
681
+ import { homedir as homedir4 } from "node:os";
682
+ import { join as join7 } from "node:path";
683
+ function assertValidSkillName(name) {
684
+ if (typeof name !== "string" || name.length === 0) {
685
+ throw new Error(`invalid skill name: empty or non-string`);
686
+ }
687
+ if (name.length > 100) {
688
+ throw new Error(`invalid skill name: too long (${name.length} chars)`);
689
+ }
690
+ if (name.includes("/") || name.includes("\\") || name.includes("..")) {
691
+ throw new Error(`invalid skill name: contains path separator or '..': ${name}`);
692
+ }
693
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {
694
+ throw new Error(`invalid skill name: must be kebab-case (lowercase a-z, 0-9, hyphen): ${name}`);
695
+ }
696
+ }
697
+ function parseFrontmatter(text) {
698
+ if (!text.startsWith("---\n") && !text.startsWith("---\r\n"))
699
+ return null;
700
+ const end = text.indexOf("\n---", 4);
701
+ if (end < 0)
702
+ return null;
703
+ const head = text.slice(4, end).trim();
704
+ const body = text.slice(end + 4).replace(/^\r?\n/, "");
705
+ const fm = { source_sessions: [] };
706
+ let mode = "kv";
707
+ for (const raw of head.split(/\r?\n/)) {
708
+ if (mode === "sources") {
709
+ const m2 = raw.match(/^\s+-\s+(.+)$/);
710
+ if (m2) {
711
+ fm.source_sessions.push(m2[1].trim());
712
+ continue;
713
+ }
714
+ mode = "kv";
715
+ }
716
+ if (raw.startsWith("source_sessions:")) {
717
+ mode = "sources";
718
+ continue;
719
+ }
720
+ const m = raw.match(/^([a-zA-Z_]+):\s*(.*)$/);
721
+ if (!m)
722
+ continue;
723
+ const [, k, v] = m;
724
+ let val = v;
725
+ if (v.startsWith('"') && v.endsWith('"')) {
726
+ try {
727
+ val = JSON.parse(v);
728
+ } catch {
729
+ }
730
+ } else if (k === "version") {
731
+ const n = parseInt(v, 10);
732
+ if (Number.isFinite(n))
733
+ val = n;
734
+ }
735
+ fm[k] = val;
736
+ }
737
+ return { fm, body };
738
+ }
739
+
740
+ // dist/src/skilify/manifest.js
741
+ import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
742
+ import { homedir as homedir5 } from "node:os";
743
+ import { dirname as dirname2, join as join8 } from "node:path";
744
+ function emptyManifest() {
745
+ return { version: 1, entries: [] };
746
+ }
747
+ function manifestPath() {
748
+ return join8(homedir5(), ".deeplake", "state", "skilify", "pulled.json");
749
+ }
750
+ function loadManifest(path = manifestPath()) {
751
+ if (!existsSync5(path))
752
+ return emptyManifest();
753
+ let raw;
754
+ try {
755
+ raw = readFileSync6(path, "utf-8");
756
+ } catch {
757
+ return emptyManifest();
758
+ }
759
+ try {
760
+ const parsed = JSON.parse(raw);
761
+ if (!parsed || typeof parsed !== "object")
762
+ return emptyManifest();
763
+ if (parsed.version !== 1 || !Array.isArray(parsed.entries))
764
+ return emptyManifest();
765
+ const entries = [];
766
+ for (const e of parsed.entries) {
767
+ if (!e || typeof e !== "object")
768
+ continue;
769
+ if (typeof e.dirName !== "string" || !e.dirName)
770
+ continue;
771
+ if (e.dirName.includes("/") || e.dirName.includes("\\") || e.dirName.includes(".."))
772
+ continue;
773
+ if (typeof e.name !== "string" || !e.name)
774
+ continue;
775
+ if (typeof e.author !== "string")
776
+ continue;
777
+ if (typeof e.installRoot !== "string" || !e.installRoot)
778
+ continue;
779
+ if (e.install !== "global" && e.install !== "project")
780
+ continue;
781
+ const symlinks = Array.isArray(e.symlinks) ? e.symlinks.filter((p) => typeof p === "string" && p.length > 0 && (p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p)) && // absolute (POSIX or Windows)
782
+ !p.includes("..")) : [];
783
+ entries.push({
784
+ dirName: e.dirName,
785
+ name: e.name,
786
+ author: e.author,
787
+ projectKey: typeof e.projectKey === "string" ? e.projectKey : "",
788
+ remoteVersion: typeof e.remoteVersion === "number" ? e.remoteVersion : 1,
789
+ install: e.install,
790
+ installRoot: e.installRoot,
791
+ pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString(),
792
+ symlinks
793
+ });
794
+ }
795
+ return { version: 1, entries };
796
+ } catch {
797
+ return emptyManifest();
798
+ }
799
+ }
800
+ function saveManifest(m, path = manifestPath()) {
801
+ mkdirSync4(dirname2(path), { recursive: true });
802
+ const tmp = `${path}.tmp`;
803
+ writeFileSync4(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
804
+ renameSync(tmp, path);
805
+ }
806
+ function recordPull(entry, path = manifestPath()) {
807
+ const m = loadManifest(path);
808
+ const idx = m.entries.findIndex((e) => e.install === entry.install && e.installRoot === entry.installRoot && e.dirName === entry.dirName);
809
+ if (idx >= 0)
810
+ m.entries[idx] = entry;
811
+ else
812
+ m.entries.push(entry);
813
+ saveManifest(m, path);
814
+ }
815
+ function entriesForRoot(m, install, installRoot) {
816
+ return m.entries.filter((e) => e.install === install && e.installRoot === installRoot);
817
+ }
818
+ function unlinkSymlinks(paths) {
819
+ for (const path of paths) {
820
+ let st;
821
+ try {
822
+ st = lstatSync(path);
823
+ } catch {
824
+ continue;
825
+ }
826
+ if (!st.isSymbolicLink())
827
+ continue;
828
+ try {
829
+ unlinkSync2(path);
830
+ } catch {
831
+ }
832
+ }
833
+ }
834
+ function pruneOrphanedEntries(path = manifestPath()) {
835
+ const m = loadManifest(path);
836
+ const live = [];
837
+ let pruned = 0;
838
+ for (const e of m.entries) {
839
+ if (existsSync5(join8(e.installRoot, e.dirName))) {
840
+ live.push(e);
841
+ continue;
842
+ }
843
+ unlinkSymlinks(e.symlinks);
844
+ pruned++;
845
+ }
846
+ if (pruned > 0)
847
+ saveManifest({ version: 1, entries: live }, path);
848
+ return pruned;
849
+ }
850
+
851
+ // dist/src/skilify/agent-roots.js
852
+ import { existsSync as existsSync6 } from "node:fs";
853
+ import { homedir as homedir6 } from "node:os";
854
+ import { join as join9 } from "node:path";
855
+ function resolveDetected(home) {
856
+ const out = [];
857
+ const codexInstalled = existsSync6(join9(home, ".codex"));
858
+ const piInstalled = existsSync6(join9(home, ".pi", "agent"));
859
+ const hermesInstalled = existsSync6(join9(home, ".hermes"));
860
+ if (codexInstalled || piInstalled) {
861
+ out.push(join9(home, ".agents", "skills"));
862
+ }
863
+ if (hermesInstalled) {
864
+ out.push(join9(home, ".hermes", "skills"));
865
+ }
866
+ if (piInstalled) {
867
+ out.push(join9(home, ".pi", "agent", "skills"));
868
+ }
869
+ return out;
870
+ }
871
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir6()) {
872
+ return resolveDetected(home).filter((p) => p !== canonicalRoot);
873
+ }
874
+
875
+ // dist/src/skilify/pull.js
876
+ function assertValidAuthor(author) {
877
+ if (!author)
878
+ throw new Error("author is empty");
879
+ if (author.length > 64)
880
+ throw new Error(`author too long (${author.length}): ${author.slice(0, 32)}\u2026`);
881
+ if (!/^[A-Za-z0-9_.\-@]+$/.test(author)) {
882
+ throw new Error(`author contains invalid characters: ${author}`);
883
+ }
884
+ }
885
+ function esc(s) {
886
+ return s.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
887
+ }
888
+ function buildPullSql(args) {
889
+ const where = [];
890
+ if (args.users.length > 0) {
891
+ const list = args.users.map((u) => `'${esc(u)}'`).join(", ");
892
+ where.push(`author IN (${list})`);
893
+ }
894
+ if (args.skillName) {
895
+ where.push(`name = '${esc(args.skillName)}'`);
896
+ }
897
+ const whereClause = where.length > 0 ? ` WHERE ${where.join(" AND ")}` : "";
898
+ return `SELECT name, project, project_key, body, version, source_agent, scope, author, description, trigger_text, source_sessions, install, created_at, updated_at FROM "${args.tableName}"${whereClause} ORDER BY project_key ASC, name ASC, version DESC`;
899
+ }
900
+ function isMissingTableError(message) {
901
+ if (!message)
902
+ return false;
903
+ return /Table does not exist|relation .* does not exist|no such table/i.test(message);
904
+ }
905
+ function resolvePullDestination(install, cwd) {
906
+ if (install === "global")
907
+ return join10(homedir7(), ".claude", "skills");
908
+ if (!cwd)
909
+ throw new Error("install=project requires a cwd");
910
+ return join10(cwd, ".claude", "skills");
911
+ }
912
+ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
913
+ const out = [];
914
+ for (const root of agentRoots) {
915
+ const link = join10(root, dirName);
916
+ let existing;
917
+ try {
918
+ existing = lstatSync2(link);
919
+ } catch {
920
+ existing = null;
921
+ }
922
+ if (existing) {
923
+ if (!existing.isSymbolicLink()) {
924
+ continue;
925
+ }
926
+ let current;
927
+ try {
928
+ current = readlinkSync(link);
929
+ } catch {
930
+ current = null;
931
+ }
932
+ if (current === canonicalDir) {
933
+ out.push(link);
934
+ continue;
935
+ }
936
+ try {
937
+ unlinkSync3(link);
938
+ } catch {
939
+ continue;
940
+ }
941
+ }
942
+ try {
943
+ mkdirSync5(dirname3(link), { recursive: true });
944
+ symlinkSync(canonicalDir, link, "dir");
945
+ out.push(link);
946
+ } catch {
947
+ }
948
+ }
949
+ return out;
950
+ }
951
+ function backfillSymlinks(installRoot) {
952
+ const manifest = loadManifest();
953
+ const entries = entriesForRoot(manifest, "global", installRoot);
954
+ if (entries.length === 0)
955
+ return;
956
+ const detected = detectAgentSkillsRoots(installRoot);
957
+ for (const entry of entries) {
958
+ const canonical = join10(entry.installRoot, entry.dirName);
959
+ if (!existsSync7(canonical))
960
+ continue;
961
+ const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
962
+ if (sameSorted(fresh, entry.symlinks))
963
+ continue;
964
+ try {
965
+ recordPull({ ...entry, symlinks: fresh });
966
+ } catch {
967
+ }
968
+ }
969
+ }
970
+ function sameSorted(a, b) {
971
+ if (a.length !== b.length)
972
+ return false;
973
+ const sa = [...a].sort();
974
+ const sb = [...b].sort();
975
+ for (let i = 0; i < sa.length; i++)
976
+ if (sa[i] !== sb[i])
977
+ return false;
978
+ return true;
979
+ }
980
+ function selectLatestPerName(rows) {
981
+ const seen = /* @__PURE__ */ new Set();
982
+ const out = [];
983
+ for (const r of rows) {
984
+ const name = String(r.name ?? "");
985
+ const projectKey = String(r.project_key ?? "");
986
+ if (!name)
987
+ continue;
988
+ const key = `${projectKey}\0${name}`;
989
+ if (seen.has(key))
990
+ continue;
991
+ seen.add(key);
992
+ out.push(r);
993
+ }
994
+ return out;
995
+ }
996
+ function renderSkillFile(row) {
997
+ const sources = parseSourceSessions(row.source_sessions);
998
+ const fm = {
999
+ name: String(row.name ?? ""),
1000
+ description: String(row.description ?? ""),
1001
+ trigger: typeof row.trigger_text === "string" && row.trigger_text.length > 0 ? String(row.trigger_text) : void 0,
1002
+ source_sessions: sources,
1003
+ version: Number(row.version ?? 1),
1004
+ created_by_agent: String(row.source_agent ?? "unknown"),
1005
+ created_at: String(row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()),
1006
+ updated_at: String(row.updated_at ?? (/* @__PURE__ */ new Date()).toISOString())
1007
+ };
1008
+ const body = String(row.body ?? "").trim();
1009
+ return `${renderFrontmatter(fm)}
1010
+
1011
+ ${body}
1012
+ `;
1013
+ }
1014
+ function parseSourceSessions(v) {
1015
+ if (Array.isArray(v))
1016
+ return v.map(String);
1017
+ if (typeof v === "string") {
1018
+ try {
1019
+ const parsed = JSON.parse(v);
1020
+ if (Array.isArray(parsed))
1021
+ return parsed.map(String);
1022
+ } catch {
1023
+ }
1024
+ }
1025
+ return [];
1026
+ }
1027
+ function renderFrontmatter(fm) {
1028
+ const lines = ["---"];
1029
+ lines.push(`name: ${fm.name}`);
1030
+ lines.push(`description: ${JSON.stringify(fm.description)}`);
1031
+ if (fm.trigger)
1032
+ lines.push(`trigger: ${JSON.stringify(fm.trigger)}`);
1033
+ lines.push(`source_sessions:`);
1034
+ for (const s of fm.source_sessions)
1035
+ lines.push(` - ${s}`);
1036
+ lines.push(`version: ${fm.version}`);
1037
+ lines.push(`created_by_agent: ${fm.created_by_agent}`);
1038
+ lines.push(`created_at: ${fm.created_at}`);
1039
+ lines.push(`updated_at: ${fm.updated_at}`);
1040
+ lines.push("---");
1041
+ return lines.join("\n");
1042
+ }
1043
+ function readLocalVersion(path) {
1044
+ if (!existsSync7(path))
1045
+ return null;
1046
+ try {
1047
+ const text = readFileSync7(path, "utf-8");
1048
+ const parsed = parseFrontmatter(text);
1049
+ if (!parsed)
1050
+ return null;
1051
+ const v = parsed.fm.version;
1052
+ return typeof v === "number" ? v : null;
1053
+ } catch {
1054
+ return null;
1055
+ }
1056
+ }
1057
+ function decideAction(args) {
1058
+ const shouldWrite = args.localVersion === null || args.remoteVersion > args.localVersion || args.force;
1059
+ if (!shouldWrite)
1060
+ return "skipped";
1061
+ return args.dryRun ? "dryrun" : "wrote";
1062
+ }
1063
+ async function runPull(opts) {
1064
+ if (!opts.dryRun)
1065
+ pruneOrphanedEntries();
1066
+ const sql = buildPullSql({
1067
+ tableName: opts.tableName,
1068
+ users: opts.users,
1069
+ skillName: opts.skillName
1070
+ });
1071
+ let rows = [];
1072
+ try {
1073
+ rows = await opts.query(sql);
1074
+ } catch (e) {
1075
+ if (isMissingTableError(e?.message))
1076
+ rows = [];
1077
+ else
1078
+ throw e;
1079
+ }
1080
+ const latest = selectLatestPerName(rows);
1081
+ const root = resolvePullDestination(opts.install, opts.cwd);
1082
+ const summary = { scanned: latest.length, wrote: 0, skipped: 0, dryrun: 0, entries: [] };
1083
+ for (const row of latest) {
1084
+ const name = String(row.name ?? "");
1085
+ if (!name)
1086
+ continue;
1087
+ try {
1088
+ assertValidSkillName(name);
1089
+ } catch (e) {
1090
+ summary.entries.push({
1091
+ name,
1092
+ remoteVersion: Number(row.version ?? 1),
1093
+ localVersion: null,
1094
+ action: "skipped",
1095
+ destination: "(invalid name \u2014 skipped)",
1096
+ author: String(row.author ?? ""),
1097
+ sourceAgent: String(row.source_agent ?? "")
1098
+ });
1099
+ summary.skipped++;
1100
+ continue;
1101
+ }
1102
+ const author = String(row.author ?? "");
1103
+ if (!author) {
1104
+ summary.entries.push({
1105
+ name,
1106
+ remoteVersion: Number(row.version ?? 1),
1107
+ localVersion: null,
1108
+ action: "skipped",
1109
+ destination: "(empty author \u2014 skipped)",
1110
+ author: "",
1111
+ sourceAgent: String(row.source_agent ?? "")
1112
+ });
1113
+ summary.skipped++;
1114
+ continue;
1115
+ }
1116
+ let dirName;
1117
+ try {
1118
+ assertValidAuthor(author);
1119
+ dirName = `${name}--${author}`;
1120
+ } catch (e) {
1121
+ summary.entries.push({
1122
+ name,
1123
+ remoteVersion: Number(row.version ?? 1),
1124
+ localVersion: null,
1125
+ action: "skipped",
1126
+ destination: `(invalid author '${author}' \u2014 skipped)`,
1127
+ author,
1128
+ sourceAgent: String(row.source_agent ?? "")
1129
+ });
1130
+ summary.skipped++;
1131
+ continue;
1132
+ }
1133
+ const skillDir = join10(root, dirName);
1134
+ const skillFile = join10(skillDir, "SKILL.md");
1135
+ const remoteVersion = Number(row.version ?? 1);
1136
+ const localVersion = readLocalVersion(skillFile);
1137
+ const action = decideAction({
1138
+ remoteVersion,
1139
+ localVersion,
1140
+ force: opts.force ?? false,
1141
+ dryRun: opts.dryRun ?? false
1142
+ });
1143
+ let manifestError;
1144
+ if (action === "wrote") {
1145
+ mkdirSync5(skillDir, { recursive: true });
1146
+ if (existsSync7(skillFile)) {
1147
+ try {
1148
+ renameSync2(skillFile, `${skillFile}.bak`);
1149
+ } catch {
1150
+ }
1151
+ }
1152
+ writeFileSync5(skillFile, renderSkillFile(row));
1153
+ const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
1154
+ try {
1155
+ recordPull({
1156
+ dirName,
1157
+ name,
1158
+ author,
1159
+ projectKey: String(row.project_key ?? ""),
1160
+ remoteVersion,
1161
+ install: opts.install,
1162
+ installRoot: root,
1163
+ pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
1164
+ symlinks
1165
+ });
1166
+ } catch (e) {
1167
+ manifestError = e?.message ?? String(e);
1168
+ }
1169
+ }
1170
+ summary.entries.push({
1171
+ name,
1172
+ remoteVersion,
1173
+ localVersion,
1174
+ action,
1175
+ destination: skillFile,
1176
+ author: String(row.author ?? ""),
1177
+ sourceAgent: String(row.source_agent ?? ""),
1178
+ manifestError
1179
+ });
1180
+ if (action === "wrote")
1181
+ summary.wrote++;
1182
+ else if (action === "dryrun")
1183
+ summary.dryrun++;
1184
+ else
1185
+ summary.skipped++;
1186
+ }
1187
+ if (!opts.dryRun && opts.install === "global") {
1188
+ backfillSymlinks(root);
1189
+ }
1190
+ return summary;
1191
+ }
1192
+
1193
+ // dist/src/skilify/auto-pull.js
1194
+ var log4 = (msg) => log("skilify-autopull", msg);
1195
+ var DEFAULT_TIMEOUT_MS = 5e3;
1196
+ function withTimeout(p, ms) {
1197
+ let timer = null;
1198
+ const timeout = new Promise((_, reject) => {
1199
+ timer = setTimeout(() => reject(new Error(`autopull timeout after ${ms}ms`)), ms);
1200
+ if (typeof timer.unref === "function")
1201
+ timer.unref();
1202
+ });
1203
+ return Promise.race([p, timeout]).finally(() => {
1204
+ if (timer)
1205
+ clearTimeout(timer);
1206
+ });
1207
+ }
1208
+ async function autoPullSkills(deps = {}) {
1209
+ if (process.env.HIVEMIND_AUTOPULL_DISABLED === "1") {
1210
+ log4("disabled via HIVEMIND_AUTOPULL_DISABLED=1");
1211
+ return { pulled: 0, skipped: true, reason: "disabled" };
1212
+ }
1213
+ const loadFn = deps.loadConfigFn ?? loadConfig;
1214
+ const config = loadFn();
1215
+ if (!config) {
1216
+ log4("skipped: not logged in");
1217
+ return { pulled: 0, skipped: true, reason: "not-logged-in" };
1218
+ }
1219
+ let query;
1220
+ if (deps.queryFn) {
1221
+ query = deps.queryFn;
1222
+ } else {
1223
+ const api = new DeeplakeApi(config.token, config.apiUrl, config.orgId, config.workspaceId, config.skillsTableName);
1224
+ query = (sql) => api.query(sql);
1225
+ }
1226
+ const install = deps.install ?? "global";
1227
+ const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
1228
+ try {
1229
+ const summary = await withTimeout(runPull({
1230
+ query,
1231
+ tableName: config.skillsTableName,
1232
+ install,
1233
+ cwd: install === "project" ? deps.cwd ?? process.cwd() : void 0,
1234
+ users: [],
1235
+ dryRun: false,
1236
+ force: false
1237
+ }), timeoutMs);
1238
+ log4(`pulled scanned=${summary.scanned} wrote=${summary.wrote} skipped=${summary.skipped}`);
1239
+ return { pulled: summary.wrote, skipped: false };
1240
+ } catch (e) {
1241
+ log4(`pull failed (swallowed): ${e?.message ?? e}`);
1242
+ return { pulled: 0, skipped: true, reason: "error" };
1243
+ }
1244
+ }
1245
+
674
1246
  // dist/src/hooks/cursor/session-start.js
675
- var log4 = (msg) => log("cursor-session-start", msg);
676
- var __bundleDir = dirname2(fileURLToPath(import.meta.url));
1247
+ var log5 = (msg) => log("cursor-session-start", msg);
1248
+ var __bundleDir = dirname4(fileURLToPath(import.meta.url));
677
1249
  var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
678
1250
 
679
1251
  Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
@@ -746,9 +1318,9 @@ async function main() {
746
1318
  const cwd = resolveCwd(input);
747
1319
  const creds = loadCredentials();
748
1320
  if (!creds?.token) {
749
- log4("no credentials found");
1321
+ log5("no credentials found");
750
1322
  } else {
751
- log4(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
1323
+ log5(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
752
1324
  }
753
1325
  await autoUpdate(creds, { agent: "cursor" });
754
1326
  const captureEnabled = process.env.HIVEMIND_CAPTURE !== "false";
@@ -762,12 +1334,14 @@ async function main() {
762
1334
  await api.ensureTable();
763
1335
  await api.ensureSessionsTable(sessionsTable);
764
1336
  await createPlaceholder(api, table, sessionId, cwd, config.userName, config.orgName, config.workspaceId);
765
- log4("placeholder created");
1337
+ log5("placeholder created");
766
1338
  }
767
1339
  } catch (e) {
768
- log4(`placeholder failed: ${e.message}`);
1340
+ log5(`placeholder failed: ${e.message}`);
769
1341
  }
770
1342
  }
1343
+ const pullResult = await autoPullSkills();
1344
+ log5(`autopull: pulled=${pullResult.pulled} skipped=${pullResult.skipped}`);
771
1345
  let versionNotice = "";
772
1346
  const current = getInstalledVersion(__bundleDir, ".claude-plugin");
773
1347
  if (current)
@@ -779,6 +1353,6 @@ Not logged in to Deeplake. Run: hivemind login${versionNotice}`;
779
1353
  console.log(JSON.stringify({ additional_context: additionalContext }));
780
1354
  }
781
1355
  main().catch((e) => {
782
- log4(`fatal: ${e.message}`);
1356
+ log5(`fatal: ${e.message}`);
783
1357
  process.exit(0);
784
1358
  });