@deeplake/hivemind 0.7.20 → 0.7.22

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.
@@ -53,9 +53,9 @@ var init_index_marker_store = __esm({
53
53
  });
54
54
 
55
55
  // dist/src/hooks/codex/stop.js
56
- import { readFileSync as readFileSync7, existsSync as existsSync9 } from "node:fs";
56
+ import { readFileSync as readFileSync8, existsSync as existsSync9 } from "node:fs";
57
57
  import { fileURLToPath as fileURLToPath3 } from "node:url";
58
- import { dirname as dirname3, join as join14 } from "node:path";
58
+ import { dirname as dirname4, join as join15 } from "node:path";
59
59
 
60
60
  // dist/src/utils/stdin.js
61
61
  function readStdin() {
@@ -512,13 +512,14 @@ var DeeplakeApi = class {
512
512
  const tables = await this.listTables();
513
513
  if (!tables.includes(tbl)) {
514
514
  log2(`table "${tbl}" not found, creating`);
515
- await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${tbl}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', summary_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'text/plain', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
515
+ await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${tbl}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', summary_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'text/plain', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
516
516
  log2(`table "${tbl}" created`);
517
517
  if (!tables.includes(tbl))
518
518
  this._tablesCache = [...tables, tbl];
519
519
  }
520
520
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
521
521
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
522
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
522
523
  }
523
524
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
524
525
  async ensureSessionsTable(name) {
@@ -526,13 +527,14 @@ var DeeplakeApi = class {
526
527
  const tables = await this.listTables();
527
528
  if (!tables.includes(safe)) {
528
529
  log2(`table "${safe}" not found, creating`);
529
- await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
530
+ await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
530
531
  log2(`table "${safe}" created`);
531
532
  if (!tables.includes(safe))
532
533
  this._tablesCache = [...tables, safe];
533
534
  }
534
535
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
535
536
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
537
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
536
538
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
537
539
  }
538
540
  /**
@@ -562,7 +564,7 @@ var DeeplakeApi = class {
562
564
  // dist/src/hooks/codex/spawn-wiki-worker.js
563
565
  import { spawn, execSync } from "node:child_process";
564
566
  import { fileURLToPath } from "node:url";
565
- import { dirname, join as join5 } from "node:path";
567
+ import { dirname as dirname2, join as join6 } from "node:path";
566
568
  import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
567
569
  import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
568
570
 
@@ -584,9 +586,51 @@ function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
584
586
  };
585
587
  }
586
588
 
589
+ // dist/src/utils/version-check.js
590
+ import { readFileSync as readFileSync3 } from "node:fs";
591
+ import { dirname, join as join5 } from "node:path";
592
+ function getInstalledVersion(bundleDir, pluginManifestDir) {
593
+ try {
594
+ const pluginJson = join5(bundleDir, "..", pluginManifestDir, "plugin.json");
595
+ const plugin = JSON.parse(readFileSync3(pluginJson, "utf-8"));
596
+ if (plugin.version)
597
+ return plugin.version;
598
+ } catch {
599
+ }
600
+ try {
601
+ const stamp = readFileSync3(join5(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
602
+ if (stamp)
603
+ return stamp;
604
+ } catch {
605
+ }
606
+ const HIVEMIND_PKG_NAMES = /* @__PURE__ */ new Set([
607
+ "hivemind",
608
+ "hivemind-codex",
609
+ "@deeplake/hivemind",
610
+ "@deeplake/hivemind-codex",
611
+ "@activeloop/hivemind",
612
+ "@activeloop/hivemind-codex"
613
+ ]);
614
+ let dir = bundleDir;
615
+ for (let i = 0; i < 5; i++) {
616
+ const candidate = join5(dir, "package.json");
617
+ try {
618
+ const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
619
+ if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
620
+ return pkg.version;
621
+ } catch {
622
+ }
623
+ const parent = dirname(dir);
624
+ if (parent === dir)
625
+ break;
626
+ dir = parent;
627
+ }
628
+ return null;
629
+ }
630
+
587
631
  // dist/src/hooks/codex/spawn-wiki-worker.js
588
632
  var HOME = homedir3();
589
- var wikiLogger = makeWikiLogger(join5(HOME, ".codex", "hooks"));
633
+ var wikiLogger = makeWikiLogger(join6(HOME, ".codex", "hooks"));
590
634
  var WIKI_LOG = wikiLogger.path;
591
635
  var WIKI_PROMPT_TEMPLATE = `You are building a personal wiki from a coding session. Your goal is to extract every piece of knowledge \u2014 entities, decisions, relationships, and facts \u2014 into a structured, searchable wiki entry.
592
636
 
@@ -648,9 +692,10 @@ function findCodexBin() {
648
692
  function spawnCodexWikiWorker(opts) {
649
693
  const { config, sessionId, cwd, bundleDir, reason } = opts;
650
694
  const projectName = cwd.split("/").pop() || "unknown";
651
- const tmpDir = join5(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
695
+ const tmpDir = join6(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
652
696
  mkdirSync3(tmpDir, { recursive: true });
653
- const configFile = join5(tmpDir, "config.json");
697
+ const pluginVersion = getInstalledVersion(bundleDir, ".codex-plugin") ?? "";
698
+ const configFile = join6(tmpDir, "config.json");
654
699
  writeFileSync2(configFile, JSON.stringify({
655
700
  apiUrl: config.apiUrl,
656
701
  token: config.token,
@@ -661,14 +706,15 @@ function spawnCodexWikiWorker(opts) {
661
706
  sessionId,
662
707
  userName: config.userName,
663
708
  project: projectName,
709
+ pluginVersion,
664
710
  tmpDir,
665
711
  codexBin: findCodexBin(),
666
712
  wikiLog: WIKI_LOG,
667
- hooksDir: join5(HOME, ".codex", "hooks"),
713
+ hooksDir: join6(HOME, ".codex", "hooks"),
668
714
  promptTemplate: WIKI_PROMPT_TEMPLATE
669
715
  }));
670
716
  wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
671
- const workerPath = join5(bundleDir, "wiki-worker.js");
717
+ const workerPath = join6(bundleDir, "wiki-worker.js");
672
718
  spawn("nohup", ["node", workerPath, configFile], {
673
719
  detached: true,
674
720
  stdio: ["ignore", "ignore", "ignore"]
@@ -676,13 +722,13 @@ function spawnCodexWikiWorker(opts) {
676
722
  wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
677
723
  }
678
724
  function bundleDirFromImportMeta(importMetaUrl) {
679
- return dirname(fileURLToPath(importMetaUrl));
725
+ return dirname2(fileURLToPath(importMetaUrl));
680
726
  }
681
727
 
682
728
  // dist/src/skillify/spawn-skillify-worker.js
683
729
  import { spawn as spawn2 } from "node:child_process";
684
730
  import { fileURLToPath as fileURLToPath2 } from "node:url";
685
- import { dirname as dirname2, join as join7 } from "node:path";
731
+ import { dirname as dirname3, join as join8 } from "node:path";
686
732
  import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
687
733
  import { homedir as homedir5, tmpdir as tmpdir3 } from "node:os";
688
734
 
@@ -690,7 +736,7 @@ import { homedir as homedir5, tmpdir as tmpdir3 } from "node:os";
690
736
  import { execFileSync } from "node:child_process";
691
737
  import { existsSync as existsSync3 } from "node:fs";
692
738
  import { homedir as homedir4 } from "node:os";
693
- import { join as join6 } from "node:path";
739
+ import { join as join7 } from "node:path";
694
740
  function findAgentBin(agent) {
695
741
  const which = (name) => {
696
742
  try {
@@ -705,24 +751,24 @@ function findAgentBin(agent) {
705
751
  };
706
752
  switch (agent) {
707
753
  case "claude_code":
708
- return which("claude") ?? join6(homedir4(), ".claude", "local", "claude");
754
+ return which("claude") ?? join7(homedir4(), ".claude", "local", "claude");
709
755
  case "codex":
710
756
  return which("codex") ?? "/usr/local/bin/codex";
711
757
  case "cursor":
712
758
  return which("cursor-agent") ?? "/usr/local/bin/cursor-agent";
713
759
  case "hermes":
714
- return which("hermes") ?? join6(homedir4(), ".local", "bin", "hermes");
760
+ return which("hermes") ?? join7(homedir4(), ".local", "bin", "hermes");
715
761
  case "pi":
716
- return which("pi") ?? join6(homedir4(), ".local", "bin", "pi");
762
+ return which("pi") ?? join7(homedir4(), ".local", "bin", "pi");
717
763
  }
718
764
  }
719
765
 
720
766
  // dist/src/skillify/spawn-skillify-worker.js
721
767
  var HOME2 = homedir5();
722
- var SKILLIFY_LOG = join7(HOME2, ".claude", "hooks", "skillify.log");
768
+ var SKILLIFY_LOG = join8(HOME2, ".claude", "hooks", "skillify.log");
723
769
  function skillifyLog(msg) {
724
770
  try {
725
- mkdirSync4(dirname2(SKILLIFY_LOG), { recursive: true });
771
+ mkdirSync4(dirname3(SKILLIFY_LOG), { recursive: true });
726
772
  appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
727
773
  `);
728
774
  } catch {
@@ -730,10 +776,10 @@ function skillifyLog(msg) {
730
776
  }
731
777
  function spawnSkillifyWorker(opts) {
732
778
  const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
733
- const tmpDir = join7(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
779
+ const tmpDir = join8(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
734
780
  mkdirSync4(tmpDir, { recursive: true, mode: 448 });
735
781
  const gateBin = findAgentBin(agent);
736
- const configFile = join7(tmpDir, "config.json");
782
+ const configFile = join8(tmpDir, "config.json");
737
783
  writeFileSync3(configFile, JSON.stringify({
738
784
  apiUrl: config.apiUrl,
739
785
  token: config.token,
@@ -764,7 +810,7 @@ function spawnSkillifyWorker(opts) {
764
810
  } catch {
765
811
  }
766
812
  skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
767
- const workerPath = join7(bundleDir, "skillify-worker.js");
813
+ const workerPath = join8(bundleDir, "skillify-worker.js");
768
814
  spawn2("nohup", ["node", workerPath, configFile], {
769
815
  detached: true,
770
816
  stdio: ["ignore", "ignore", "ignore"]
@@ -773,25 +819,25 @@ function spawnSkillifyWorker(opts) {
773
819
  }
774
820
 
775
821
  // dist/src/skillify/state.js
776
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, writeSync, mkdirSync as mkdirSync5, renameSync as renameSync2, existsSync as existsSync5, unlinkSync, openSync, closeSync } from "node:fs";
822
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, writeSync, mkdirSync as mkdirSync5, renameSync as renameSync2, existsSync as existsSync5, unlinkSync, openSync, closeSync } from "node:fs";
777
823
  import { execSync as execSync2 } from "node:child_process";
778
824
  import { homedir as homedir7 } from "node:os";
779
825
  import { createHash } from "node:crypto";
780
- import { join as join9, basename } from "node:path";
826
+ import { join as join10, basename } from "node:path";
781
827
 
782
828
  // dist/src/skillify/legacy-migration.js
783
829
  import { existsSync as existsSync4, renameSync } from "node:fs";
784
830
  import { homedir as homedir6 } from "node:os";
785
- import { join as join8 } from "node:path";
831
+ import { join as join9 } from "node:path";
786
832
  var dlog = (msg) => log("skillify-migrate", msg);
787
833
  var attempted = false;
788
834
  function migrateLegacyStateDir() {
789
835
  if (attempted)
790
836
  return;
791
837
  attempted = true;
792
- const root = join8(homedir6(), ".deeplake", "state");
793
- const legacy = join8(root, "skilify");
794
- const current = join8(root, "skillify");
838
+ const root = join9(homedir6(), ".deeplake", "state");
839
+ const legacy = join9(root, "skilify");
840
+ const current = join9(root, "skillify");
795
841
  if (!existsSync4(legacy))
796
842
  return;
797
843
  if (existsSync4(current))
@@ -811,17 +857,17 @@ function migrateLegacyStateDir() {
811
857
 
812
858
  // dist/src/skillify/state.js
813
859
  var dlog2 = (msg) => log("skillify-state", msg);
814
- var STATE_DIR = join9(homedir7(), ".deeplake", "state", "skillify");
860
+ var STATE_DIR = join10(homedir7(), ".deeplake", "state", "skillify");
815
861
  var YIELD_BUF = new Int32Array(new SharedArrayBuffer(4));
816
862
  var TRIGGER_THRESHOLD = (() => {
817
863
  const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
818
864
  return Number.isInteger(n) && n > 0 ? n : 20;
819
865
  })();
820
866
  function statePath(projectKey) {
821
- return join9(STATE_DIR, `${projectKey}.json`);
867
+ return join10(STATE_DIR, `${projectKey}.json`);
822
868
  }
823
869
  function lockPath(projectKey) {
824
- return join9(STATE_DIR, `${projectKey}.lock`);
870
+ return join10(STATE_DIR, `${projectKey}.lock`);
825
871
  }
826
872
  var DEFAULT_PORTS = {
827
873
  http: "80",
@@ -870,7 +916,7 @@ function readState(projectKey) {
870
916
  if (!existsSync5(p))
871
917
  return null;
872
918
  try {
873
- return JSON.parse(readFileSync3(p, "utf-8"));
919
+ return JSON.parse(readFileSync4(p, "utf-8"));
874
920
  } catch {
875
921
  return null;
876
922
  }
@@ -932,7 +978,7 @@ function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
932
978
  const p = lockPath(projectKey);
933
979
  if (existsSync5(p)) {
934
980
  try {
935
- const ageMs = Date.now() - parseInt(readFileSync3(p, "utf-8"), 10);
981
+ const ageMs = Date.now() - parseInt(readFileSync4(p, "utf-8"), 10);
936
982
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
937
983
  return false;
938
984
  } catch (readErr) {
@@ -966,18 +1012,18 @@ function releaseWorkerLock(projectKey) {
966
1012
  }
967
1013
 
968
1014
  // dist/src/skillify/scope-config.js
969
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
1015
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
970
1016
  import { homedir as homedir8 } from "node:os";
971
- import { join as join10 } from "node:path";
972
- var STATE_DIR2 = join10(homedir8(), ".deeplake", "state", "skillify");
973
- var CONFIG_PATH = join10(STATE_DIR2, "config.json");
1017
+ import { join as join11 } from "node:path";
1018
+ var STATE_DIR2 = join11(homedir8(), ".deeplake", "state", "skillify");
1019
+ var CONFIG_PATH = join11(STATE_DIR2, "config.json");
974
1020
  var DEFAULT = { scope: "me", team: [], install: "project" };
975
1021
  function loadScopeConfig() {
976
1022
  migrateLegacyStateDir();
977
1023
  if (!existsSync6(CONFIG_PATH))
978
1024
  return DEFAULT;
979
1025
  try {
980
- const raw = JSON.parse(readFileSync4(CONFIG_PATH, "utf-8"));
1026
+ const raw = JSON.parse(readFileSync5(CONFIG_PATH, "utf-8"));
981
1027
  const scope = raw.scope === "team" || raw.scope === "org" ? raw.scope : "me";
982
1028
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
983
1029
  const install = raw.install === "global" ? "global" : "project";
@@ -1028,21 +1074,21 @@ function forceSessionEndTrigger(opts) {
1028
1074
  }
1029
1075
 
1030
1076
  // dist/src/hooks/summary-state.js
1031
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync6, writeSync as writeSync2, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync7, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
1077
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, writeSync as writeSync2, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync7, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
1032
1078
  import { homedir as homedir9 } from "node:os";
1033
- import { join as join11 } from "node:path";
1079
+ import { join as join12 } from "node:path";
1034
1080
  var dlog3 = (msg) => log("summary-state", msg);
1035
- var STATE_DIR3 = join11(homedir9(), ".claude", "hooks", "summary-state");
1081
+ var STATE_DIR3 = join12(homedir9(), ".claude", "hooks", "summary-state");
1036
1082
  var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
1037
1083
  function lockPath2(sessionId) {
1038
- return join11(STATE_DIR3, `${sessionId}.lock`);
1084
+ return join12(STATE_DIR3, `${sessionId}.lock`);
1039
1085
  }
1040
1086
  function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1041
1087
  mkdirSync7(STATE_DIR3, { recursive: true });
1042
1088
  const p = lockPath2(sessionId);
1043
1089
  if (existsSync7(p)) {
1044
1090
  try {
1045
- const ageMs = Date.now() - parseInt(readFileSync5(p, "utf-8"), 10);
1091
+ const ageMs = Date.now() - parseInt(readFileSync6(p, "utf-8"), 10);
1046
1092
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
1047
1093
  return false;
1048
1094
  } catch (readErr) {
@@ -1088,9 +1134,9 @@ function buildSessionPath(config, sessionId) {
1088
1134
  // dist/src/embeddings/client.js
1089
1135
  import { connect } from "node:net";
1090
1136
  import { spawn as spawn3 } from "node:child_process";
1091
- import { openSync as openSync3, closeSync as closeSync3, writeSync as writeSync3, unlinkSync as unlinkSync3, existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
1137
+ import { openSync as openSync3, closeSync as closeSync3, writeSync as writeSync3, unlinkSync as unlinkSync3, existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
1092
1138
  import { homedir as homedir10 } from "node:os";
1093
- import { join as join12 } from "node:path";
1139
+ import { join as join13 } from "node:path";
1094
1140
 
1095
1141
  // dist/src/embeddings/protocol.js
1096
1142
  var DEFAULT_SOCKET_DIR = "/tmp";
@@ -1104,7 +1150,7 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
1104
1150
  }
1105
1151
 
1106
1152
  // dist/src/embeddings/client.js
1107
- var SHARED_DAEMON_PATH = join12(homedir10(), ".hivemind", "embed-deps", "embed-daemon.js");
1153
+ var SHARED_DAEMON_PATH = join13(homedir10(), ".hivemind", "embed-deps", "embed-daemon.js");
1108
1154
  var log3 = (m) => log("embed-client", m);
1109
1155
  function getUid() {
1110
1156
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
@@ -1247,7 +1293,7 @@ var EmbedClient = class {
1247
1293
  }
1248
1294
  isPidFileStale() {
1249
1295
  try {
1250
- const raw = readFileSync6(this.pidPath, "utf-8").trim();
1296
+ const raw = readFileSync7(this.pidPath, "utf-8").trim();
1251
1297
  const pid = Number(raw);
1252
1298
  if (!pid || Number.isNaN(pid))
1253
1299
  return true;
@@ -1329,7 +1375,7 @@ function embeddingSqlLiteral(vec) {
1329
1375
  // dist/src/embeddings/disable.js
1330
1376
  import { createRequire } from "node:module";
1331
1377
  import { homedir as homedir11 } from "node:os";
1332
- import { join as join13 } from "node:path";
1378
+ import { join as join14 } from "node:path";
1333
1379
  import { pathToFileURL } from "node:url";
1334
1380
  var cachedStatus = null;
1335
1381
  function defaultResolveTransformers() {
@@ -1338,7 +1384,7 @@ function defaultResolveTransformers() {
1338
1384
  return;
1339
1385
  } catch {
1340
1386
  }
1341
- const sharedDir = join13(homedir11(), ".hivemind", "embed-deps");
1387
+ const sharedDir = join14(homedir11(), ".hivemind", "embed-deps");
1342
1388
  createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
1343
1389
  }
1344
1390
  var _resolve = defaultResolveTransformers;
@@ -1365,8 +1411,10 @@ function embeddingsDisabled() {
1365
1411
  // dist/src/hooks/codex/stop.js
1366
1412
  var log4 = (msg) => log("codex-stop", msg);
1367
1413
  function resolveEmbedDaemonPath() {
1368
- return join14(dirname3(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1414
+ return join15(dirname4(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1369
1415
  }
1416
+ var __bundleDir = dirname4(fileURLToPath3(import.meta.url));
1417
+ var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".codex-plugin") ?? "";
1370
1418
  var CAPTURE = process.env.HIVEMIND_CAPTURE !== "false";
1371
1419
  async function main() {
1372
1420
  if (process.env.HIVEMIND_WIKI_WORKER === "1")
@@ -1390,7 +1438,7 @@ async function main() {
1390
1438
  try {
1391
1439
  const transcriptPath = input.transcript_path;
1392
1440
  if (existsSync9(transcriptPath)) {
1393
- const transcript = readFileSync7(transcriptPath, "utf-8");
1441
+ const transcript = readFileSync8(transcriptPath, "utf-8");
1394
1442
  const lines = transcript.trim().split("\n").reverse();
1395
1443
  for (const line2 of lines) {
1396
1444
  try {
@@ -1431,7 +1479,7 @@ async function main() {
1431
1479
  const jsonForSql = line.replace(/'/g, "''");
1432
1480
  const embedding = embeddingsDisabled() ? null : await new EmbedClient({ daemonEntry: resolveEmbedDaemonPath() }).embed(line, "document");
1433
1481
  const embeddingSql = embeddingSqlLiteral(embedding);
1434
- const insertSql = `INSERT INTO "${sessionsTable}" (id, path, filename, message, message_embedding, author, size_bytes, project, description, agent, creation_date, last_update_date) VALUES ('${crypto.randomUUID()}', '${sqlStr(sessionPath)}', '${sqlStr(filename)}', '${jsonForSql}'::jsonb, ${embeddingSql}, '${sqlStr(config.userName)}', ${Buffer.byteLength(line, "utf-8")}, '${sqlStr(projectName)}', 'Stop', 'codex', '${ts}', '${ts}')`;
1482
+ const insertSql = `INSERT INTO "${sessionsTable}" (id, path, filename, message, message_embedding, author, size_bytes, project, description, agent, plugin_version, creation_date, last_update_date) VALUES ('${crypto.randomUUID()}', '${sqlStr(sessionPath)}', '${sqlStr(filename)}', '${jsonForSql}'::jsonb, ${embeddingSql}, '${sqlStr(config.userName)}', ${Buffer.byteLength(line, "utf-8")}, '${sqlStr(projectName)}', 'Stop', 'codex', '${sqlStr(PLUGIN_VERSION)}', '${ts}', '${ts}')`;
1435
1483
  await api.query(insertSql);
1436
1484
  log4("stop event captured");
1437
1485
  } catch (e) {
@@ -135,13 +135,16 @@ async function uploadSummary(query2, params) {
135
135
  const desc = extractDescription(text);
136
136
  const sizeBytes = Buffer.byteLength(text);
137
137
  const embSql = embeddingSqlLiteral(params.embedding ?? null);
138
+ const pluginVersion = params.pluginVersion;
138
139
  const existing = await query2(`SELECT path FROM "${tableName}" WHERE path = '${esc(vpath)}' LIMIT 1`);
139
140
  if (existing.length > 0) {
140
- const sql2 = `UPDATE "${tableName}" SET summary = E'${esc(text)}', summary_embedding = ${embSql}, size_bytes = ${sizeBytes}, description = E'${esc(desc)}', last_update_date = '${ts}' WHERE path = '${esc(vpath)}'`;
141
+ const pluginVersionSet = pluginVersion === void 0 ? "" : `plugin_version = '${esc(pluginVersion)}', `;
142
+ const sql2 = `UPDATE "${tableName}" SET summary = E'${esc(text)}', summary_embedding = ${embSql}, size_bytes = ${sizeBytes}, description = E'${esc(desc)}', ` + pluginVersionSet + `last_update_date = '${ts}' WHERE path = '${esc(vpath)}'`;
141
143
  await query2(sql2);
142
144
  return { path: "update", sql: sql2, descLength: desc.length, summaryLength: text.length };
143
145
  }
144
- const sql = `INSERT INTO "${tableName}" (id, path, filename, summary, summary_embedding, author, mime_type, size_bytes, project, description, agent, creation_date, last_update_date) VALUES ('${randomUUID()}', '${esc(vpath)}', '${esc(fname)}', E'${esc(text)}', ${embSql}, '${esc(userName)}', 'text/markdown', ${sizeBytes}, '${esc(project)}', E'${esc(desc)}', '${esc(agent)}', '${ts}', '${ts}')`;
146
+ const pluginVersionForInsert = pluginVersion ?? "";
147
+ const sql = `INSERT INTO "${tableName}" (id, path, filename, summary, summary_embedding, author, mime_type, size_bytes, project, description, agent, plugin_version, creation_date, last_update_date) VALUES ('${randomUUID()}', '${esc(vpath)}', '${esc(fname)}', E'${esc(text)}', ${embSql}, '${esc(userName)}', 'text/markdown', ${sizeBytes}, '${esc(project)}', E'${esc(desc)}', '${esc(agent)}', '${esc(pluginVersionForInsert)}', '${ts}', '${ts}')`;
145
148
  await query2(sql);
146
149
  return { path: "insert", sql, descLength: desc.length, summaryLength: text.length };
147
150
  }
@@ -539,7 +542,8 @@ async function main() {
539
542
  agent: "codex",
540
543
  sessionId: cfg.sessionId,
541
544
  text,
542
- embedding
545
+ embedding,
546
+ pluginVersion: cfg.pluginVersion ?? ""
543
547
  });
544
548
  wlog(`uploaded ${vpath} (summary=${result.summaryLength}, desc=${result.descLength})`);
545
549
  try {