@deeplake/hivemind 0.7.21 → 0.7.23

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.
Files changed (37) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +1 -1
  4. package/bundle/cli.js +66 -15
  5. package/codex/bundle/capture.js +60 -12
  6. package/codex/bundle/commands/auth-login.js +4 -2
  7. package/codex/bundle/pre-tool-use.js +4 -2
  8. package/codex/bundle/session-start-setup.js +52 -5
  9. package/codex/bundle/session-start.js +62 -11
  10. package/codex/bundle/shell/deeplake-shell.js +4 -2
  11. package/codex/bundle/skillify-worker.js +118 -29
  12. package/codex/bundle/stop.js +100 -52
  13. package/codex/bundle/wiki-worker.js +7 -3
  14. package/cursor/bundle/capture.js +87 -39
  15. package/cursor/bundle/commands/auth-login.js +4 -2
  16. package/cursor/bundle/pre-tool-use.js +4 -2
  17. package/cursor/bundle/session-end.js +78 -34
  18. package/cursor/bundle/session-start.js +67 -15
  19. package/cursor/bundle/shell/deeplake-shell.js +4 -2
  20. package/cursor/bundle/skillify-worker.js +118 -29
  21. package/cursor/bundle/wiki-worker.js +7 -3
  22. package/hermes/bundle/capture.js +87 -39
  23. package/hermes/bundle/commands/auth-login.js +4 -2
  24. package/hermes/bundle/pre-tool-use.js +4 -2
  25. package/hermes/bundle/session-end.js +78 -34
  26. package/hermes/bundle/session-start.js +67 -15
  27. package/hermes/bundle/shell/deeplake-shell.js +4 -2
  28. package/hermes/bundle/skillify-worker.js +118 -29
  29. package/hermes/bundle/wiki-worker.js +7 -3
  30. package/mcp/bundle/server.js +4 -2
  31. package/openclaw/dist/index.js +8 -6
  32. package/openclaw/dist/skillify-worker.js +118 -29
  33. package/openclaw/openclaw.plugin.json +1 -1
  34. package/openclaw/package.json +1 -1
  35. package/openclaw/skills/SKILL.md +1 -1
  36. package/package.json +1 -1
  37. package/pi/extension-source/hivemind.ts +18 -3
@@ -6,13 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
9
- "version": "0.7.21"
9
+ "version": "0.7.23"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "hivemind",
14
14
  "description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
15
- "version": "0.7.21",
15
+ "version": "0.7.23",
16
16
  "source": "./claude-code",
17
17
  "homepage": "https://github.com/activeloopai/hivemind"
18
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hivemind",
3
3
  "description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
4
- "version": "0.7.21",
4
+ "version": "0.7.23",
5
5
  "author": {
6
6
  "name": "Activeloop",
7
7
  "url": "https://deeplake.ai"
package/README.md CHANGED
@@ -268,7 +268,7 @@ Hivemind **codifies recurring patterns from your team's recent sessions into reu
268
268
 
269
269
  ```bash
270
270
  hivemind skillify # show current scope, team, install, per-project state
271
- hivemind skillify scope <me|team|org> # who counts as "in scope" for mining
271
+ hivemind skillify scope <me|team> # who counts as "in scope" for mining
272
272
  hivemind skillify pull # install teammates' skills locally
273
273
  hivemind skillify unpull # remove pulled skills
274
274
  ```
package/bundle/cli.js CHANGED
@@ -4344,13 +4344,14 @@ var DeeplakeApi = class {
4344
4344
  const tables = await this.listTables();
4345
4345
  if (!tables.includes(tbl)) {
4346
4346
  log3(`table "${tbl}" not found, creating`);
4347
- 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);
4347
+ 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);
4348
4348
  log3(`table "${tbl}" created`);
4349
4349
  if (!tables.includes(tbl))
4350
4350
  this._tablesCache = [...tables, tbl];
4351
4351
  }
4352
4352
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
4353
4353
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
4354
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
4354
4355
  }
4355
4356
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
4356
4357
  async ensureSessionsTable(name) {
@@ -4358,13 +4359,14 @@ var DeeplakeApi = class {
4358
4359
  const tables = await this.listTables();
4359
4360
  if (!tables.includes(safe)) {
4360
4361
  log3(`table "${safe}" not found, creating`);
4361
- 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);
4362
+ 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);
4362
4363
  log3(`table "${safe}" created`);
4363
4364
  if (!tables.includes(safe))
4364
4365
  this._tablesCache = [...tables, safe];
4365
4366
  }
4366
4367
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
4367
4368
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
4369
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
4368
4370
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
4369
4371
  }
4370
4372
  /**
@@ -4768,7 +4770,7 @@ function loadScopeConfig() {
4768
4770
  return DEFAULT;
4769
4771
  try {
4770
4772
  const raw = JSON.parse(readFileSync9(CONFIG_PATH2, "utf-8"));
4771
- const scope = raw.scope === "team" || raw.scope === "org" ? raw.scope : "me";
4773
+ const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
4772
4774
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
4773
4775
  const install = raw.install === "global" ? "global" : "project";
4774
4776
  return { scope, team, install };
@@ -4814,18 +4816,25 @@ function parseFrontmatter(text) {
4814
4816
  const head = text.slice(4, end).trim();
4815
4817
  const body = text.slice(end + 4).replace(/^\r?\n/, "");
4816
4818
  const fm = { source_sessions: [] };
4817
- let mode = "kv";
4819
+ let arrayKey = null;
4818
4820
  for (const raw of head.split(/\r?\n/)) {
4819
- if (mode === "sources") {
4821
+ if (arrayKey) {
4820
4822
  const m2 = raw.match(/^\s+-\s+(.+)$/);
4821
4823
  if (m2) {
4822
- fm.source_sessions.push(m2[1].trim());
4824
+ const arr = fm[arrayKey] ?? [];
4825
+ arr.push(m2[1].trim());
4826
+ fm[arrayKey] = arr;
4823
4827
  continue;
4824
4828
  }
4825
- mode = "kv";
4829
+ arrayKey = null;
4826
4830
  }
4827
4831
  if (raw.startsWith("source_sessions:")) {
4828
- mode = "sources";
4832
+ arrayKey = "source_sessions";
4833
+ continue;
4834
+ }
4835
+ if (raw.startsWith("contributors:")) {
4836
+ arrayKey = "contributors";
4837
+ fm.contributors = [];
4829
4838
  continue;
4830
4839
  }
4831
4840
  const m = raw.match(/^([a-zA-Z_]+):\s*(.*)$/);
@@ -5015,11 +5024,19 @@ function buildPullSql(args) {
5015
5024
  where.push(`name = '${esc(args.skillName)}'`);
5016
5025
  }
5017
5026
  const whereClause = where.length > 0 ? ` WHERE ${where.join(" AND ")}` : "";
5018
- 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`;
5027
+ const contributorsCol = args.includeContributors === false ? "" : "contributors, ";
5028
+ return `SELECT name, project, project_key, body, version, source_agent, scope, author, ${contributorsCol}description, trigger_text, source_sessions, install, created_at, updated_at FROM "${args.tableName}"${whereClause} ORDER BY project_key ASC, name ASC, version DESC`;
5029
+ }
5030
+ function isMissingContributorsColumnError(message) {
5031
+ if (!message)
5032
+ return false;
5033
+ return /contributors.*(?:does not exist|not found|unknown)/i.test(message) || /(?:does not exist|unknown column).*contributors/i.test(message);
5019
5034
  }
5020
5035
  function isMissingTableError(message) {
5021
5036
  if (!message)
5022
5037
  return false;
5038
+ if (/\bcolumn\b/i.test(message))
5039
+ return false;
5023
5040
  return /Table does not exist|relation .* does not exist|no such table/i.test(message);
5024
5041
  }
5025
5042
  function resolvePullDestination(install, cwd) {
@@ -5115,11 +5132,16 @@ function selectLatestPerName(rows) {
5115
5132
  }
5116
5133
  function renderSkillFile(row) {
5117
5134
  const sources = parseSourceSessions(row.source_sessions);
5135
+ const author = typeof row.author === "string" && row.author.length > 0 ? row.author : void 0;
5136
+ const contributors = parseContributors(row.contributors);
5137
+ const renderedContributors = contributors.length > 0 ? contributors : author ? [author] : [];
5118
5138
  const fm = {
5119
5139
  name: String(row.name ?? ""),
5120
5140
  description: String(row.description ?? ""),
5121
5141
  trigger: typeof row.trigger_text === "string" && row.trigger_text.length > 0 ? String(row.trigger_text) : void 0,
5142
+ author,
5122
5143
  source_sessions: sources,
5144
+ contributors: renderedContributors,
5123
5145
  version: Number(row.version ?? 1),
5124
5146
  created_by_agent: String(row.source_agent ?? "unknown"),
5125
5147
  created_at: String(row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()),
@@ -5144,15 +5166,35 @@ function parseSourceSessions(v) {
5144
5166
  }
5145
5167
  return [];
5146
5168
  }
5169
+ function parseContributors(v) {
5170
+ if (Array.isArray(v))
5171
+ return v.map(String);
5172
+ if (typeof v === "string") {
5173
+ try {
5174
+ const parsed = JSON.parse(v);
5175
+ if (Array.isArray(parsed))
5176
+ return parsed.map(String);
5177
+ } catch {
5178
+ }
5179
+ }
5180
+ return [];
5181
+ }
5147
5182
  function renderFrontmatter(fm) {
5148
5183
  const lines = ["---"];
5149
5184
  lines.push(`name: ${fm.name}`);
5150
5185
  lines.push(`description: ${JSON.stringify(fm.description)}`);
5151
5186
  if (fm.trigger)
5152
5187
  lines.push(`trigger: ${JSON.stringify(fm.trigger)}`);
5188
+ if (fm.author)
5189
+ lines.push(`author: ${fm.author}`);
5153
5190
  lines.push(`source_sessions:`);
5154
5191
  for (const s of fm.source_sessions)
5155
5192
  lines.push(` - ${s}`);
5193
+ if (fm.contributors && fm.contributors.length > 0) {
5194
+ lines.push(`contributors:`);
5195
+ for (const c of fm.contributors)
5196
+ lines.push(` - ${c}`);
5197
+ }
5156
5198
  lines.push(`version: ${fm.version}`);
5157
5199
  lines.push(`created_by_agent: ${fm.created_by_agent}`);
5158
5200
  lines.push(`created_at: ${fm.created_at}`);
@@ -5192,10 +5234,19 @@ async function runPull(opts) {
5192
5234
  try {
5193
5235
  rows = await opts.query(sql);
5194
5236
  } catch (e) {
5195
- if (isMissingTableError(e?.message))
5237
+ if (isMissingTableError(e?.message)) {
5196
5238
  rows = [];
5197
- else
5239
+ } else if (isMissingContributorsColumnError(e?.message)) {
5240
+ const legacySql = buildPullSql({
5241
+ tableName: opts.tableName,
5242
+ users: opts.users,
5243
+ skillName: opts.skillName,
5244
+ includeContributors: false
5245
+ });
5246
+ rows = await opts.query(legacySql);
5247
+ } else {
5198
5248
  throw e;
5249
+ }
5199
5250
  }
5200
5251
  const latest = selectLatestPerName(rows);
5201
5252
  const root = resolvePullDestination(opts.install, opts.cwd);
@@ -5509,8 +5560,8 @@ function showStatus() {
5509
5560
  }
5510
5561
  }
5511
5562
  function setScope(scope) {
5512
- if (scope !== "me" && scope !== "team" && scope !== "org") {
5513
- console.error(`Invalid scope '${scope}'. Use one of: me, team, org`);
5563
+ if (scope !== "me" && scope !== "team") {
5564
+ console.error(`Invalid scope '${scope}'. Use one of: me, team`);
5514
5565
  process.exit(1);
5515
5566
  }
5516
5567
  const cfg = loadScopeConfig();
@@ -5589,7 +5640,7 @@ function teamList() {
5589
5640
  function usage() {
5590
5641
  console.log("Usage:");
5591
5642
  console.log(" hivemind skillify show current scope, team, install, and per-project state");
5592
- console.log(" hivemind skillify scope <me|team|org> set the mining scope");
5643
+ console.log(" hivemind skillify scope <me|team> set the mining scope");
5593
5644
  console.log(" hivemind skillify install <project|global> set where new skills are written");
5594
5645
  console.log(" hivemind skillify promote <skill-name> move a project skill to the global location");
5595
5646
  console.log(" hivemind skillify team add <username> add a username to the team list");
@@ -6039,7 +6090,7 @@ Skill management (mine + share reusable Claude skills across the org):
6039
6090
  --to <project|global>, --dry-run,
6040
6091
  --all (also locally-mined),
6041
6092
  --legacy-cleanup (pre-suffix-author dirs).
6042
- hivemind skillify scope <me|team|org> Set the sharing scope for newly mined skills.
6093
+ hivemind skillify scope <me|team> Set the sharing scope for newly mined skills.
6043
6094
  hivemind skillify install <project|global> Set where new skills are written.
6044
6095
  hivemind skillify promote <name> Move a project skill to the global location.
6045
6096
  hivemind skillify team add <username> Add a username to the team list.
@@ -507,13 +507,14 @@ var DeeplakeApi = class {
507
507
  const tables = await this.listTables();
508
508
  if (!tables.includes(tbl)) {
509
509
  log2(`table "${tbl}" not found, creating`);
510
- 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);
510
+ 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);
511
511
  log2(`table "${tbl}" created`);
512
512
  if (!tables.includes(tbl))
513
513
  this._tablesCache = [...tables, tbl];
514
514
  }
515
515
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
516
516
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
517
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
517
518
  }
518
519
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
519
520
  async ensureSessionsTable(name) {
@@ -521,13 +522,14 @@ var DeeplakeApi = class {
521
522
  const tables = await this.listTables();
522
523
  if (!tables.includes(safe)) {
523
524
  log2(`table "${safe}" not found, creating`);
524
- 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);
525
+ 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);
525
526
  log2(`table "${safe}" created`);
526
527
  if (!tables.includes(safe))
527
528
  this._tablesCache = [...tables, safe];
528
529
  }
529
530
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
530
531
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
532
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
531
533
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
532
534
  }
533
535
  /**
@@ -839,7 +841,7 @@ function embeddingsDisabled() {
839
841
 
840
842
  // dist/src/hooks/codex/capture.js
841
843
  import { fileURLToPath as fileURLToPath2 } from "node:url";
842
- import { dirname as dirname2, join as join9 } from "node:path";
844
+ import { dirname as dirname3, join as join10 } from "node:path";
843
845
 
844
846
  // dist/src/hooks/summary-state.js
845
847
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, writeSync as writeSync2, mkdirSync as mkdirSync2, renameSync, existsSync as existsSync4, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
@@ -978,7 +980,7 @@ function releaseLock(sessionId) {
978
980
  // dist/src/hooks/codex/spawn-wiki-worker.js
979
981
  import { spawn as spawn2, execSync } from "node:child_process";
980
982
  import { fileURLToPath } from "node:url";
981
- import { dirname, join as join8 } from "node:path";
983
+ import { dirname as dirname2, join as join9 } from "node:path";
982
984
  import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "node:fs";
983
985
  import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
984
986
 
@@ -1000,9 +1002,51 @@ function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1000
1002
  };
1001
1003
  }
1002
1004
 
1005
+ // dist/src/utils/version-check.js
1006
+ import { readFileSync as readFileSync5 } from "node:fs";
1007
+ import { dirname, join as join8 } from "node:path";
1008
+ function getInstalledVersion(bundleDir, pluginManifestDir) {
1009
+ try {
1010
+ const pluginJson = join8(bundleDir, "..", pluginManifestDir, "plugin.json");
1011
+ const plugin = JSON.parse(readFileSync5(pluginJson, "utf-8"));
1012
+ if (plugin.version)
1013
+ return plugin.version;
1014
+ } catch {
1015
+ }
1016
+ try {
1017
+ const stamp = readFileSync5(join8(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
1018
+ if (stamp)
1019
+ return stamp;
1020
+ } catch {
1021
+ }
1022
+ const HIVEMIND_PKG_NAMES = /* @__PURE__ */ new Set([
1023
+ "hivemind",
1024
+ "hivemind-codex",
1025
+ "@deeplake/hivemind",
1026
+ "@deeplake/hivemind-codex",
1027
+ "@activeloop/hivemind",
1028
+ "@activeloop/hivemind-codex"
1029
+ ]);
1030
+ let dir = bundleDir;
1031
+ for (let i = 0; i < 5; i++) {
1032
+ const candidate = join8(dir, "package.json");
1033
+ try {
1034
+ const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
1035
+ if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
1036
+ return pkg.version;
1037
+ } catch {
1038
+ }
1039
+ const parent = dirname(dir);
1040
+ if (parent === dir)
1041
+ break;
1042
+ dir = parent;
1043
+ }
1044
+ return null;
1045
+ }
1046
+
1003
1047
  // dist/src/hooks/codex/spawn-wiki-worker.js
1004
1048
  var HOME = homedir6();
1005
- var wikiLogger = makeWikiLogger(join8(HOME, ".codex", "hooks"));
1049
+ var wikiLogger = makeWikiLogger(join9(HOME, ".codex", "hooks"));
1006
1050
  var WIKI_LOG = wikiLogger.path;
1007
1051
  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.
1008
1052
 
@@ -1064,9 +1108,10 @@ function findCodexBin() {
1064
1108
  function spawnCodexWikiWorker(opts) {
1065
1109
  const { config, sessionId, cwd, bundleDir, reason } = opts;
1066
1110
  const projectName = cwd.split("/").pop() || "unknown";
1067
- const tmpDir = join8(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
1111
+ const tmpDir = join9(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
1068
1112
  mkdirSync4(tmpDir, { recursive: true });
1069
- const configFile = join8(tmpDir, "config.json");
1113
+ const pluginVersion = getInstalledVersion(bundleDir, ".codex-plugin") ?? "";
1114
+ const configFile = join9(tmpDir, "config.json");
1070
1115
  writeFileSync3(configFile, JSON.stringify({
1071
1116
  apiUrl: config.apiUrl,
1072
1117
  token: config.token,
@@ -1077,14 +1122,15 @@ function spawnCodexWikiWorker(opts) {
1077
1122
  sessionId,
1078
1123
  userName: config.userName,
1079
1124
  project: projectName,
1125
+ pluginVersion,
1080
1126
  tmpDir,
1081
1127
  codexBin: findCodexBin(),
1082
1128
  wikiLog: WIKI_LOG,
1083
- hooksDir: join8(HOME, ".codex", "hooks"),
1129
+ hooksDir: join9(HOME, ".codex", "hooks"),
1084
1130
  promptTemplate: WIKI_PROMPT_TEMPLATE
1085
1131
  }));
1086
1132
  wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
1087
- const workerPath = join8(bundleDir, "wiki-worker.js");
1133
+ const workerPath = join9(bundleDir, "wiki-worker.js");
1088
1134
  spawn2("nohup", ["node", workerPath, configFile], {
1089
1135
  detached: true,
1090
1136
  stdio: ["ignore", "ignore", "ignore"]
@@ -1092,14 +1138,16 @@ function spawnCodexWikiWorker(opts) {
1092
1138
  wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
1093
1139
  }
1094
1140
  function bundleDirFromImportMeta(importMetaUrl) {
1095
- return dirname(fileURLToPath(importMetaUrl));
1141
+ return dirname2(fileURLToPath(importMetaUrl));
1096
1142
  }
1097
1143
 
1098
1144
  // dist/src/hooks/codex/capture.js
1099
1145
  var log4 = (msg) => log("codex-capture", msg);
1100
1146
  function resolveEmbedDaemonPath() {
1101
- return join9(dirname2(fileURLToPath2(import.meta.url)), "embeddings", "embed-daemon.js");
1147
+ return join10(dirname3(fileURLToPath2(import.meta.url)), "embeddings", "embed-daemon.js");
1102
1148
  }
1149
+ var __bundleDir = dirname3(fileURLToPath2(import.meta.url));
1150
+ var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".codex-plugin") ?? "";
1103
1151
  var CAPTURE = process.env.HIVEMIND_CAPTURE !== "false";
1104
1152
  async function main() {
1105
1153
  if (!CAPTURE)
@@ -1154,7 +1202,7 @@ async function main() {
1154
1202
  const jsonForSql = line.replace(/'/g, "''");
1155
1203
  const embedding = embeddingsDisabled() ? null : await new EmbedClient({ daemonEntry: resolveEmbedDaemonPath() }).embed(line, "document");
1156
1204
  const embeddingSql = embeddingSqlLiteral(embedding);
1157
- 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)}', '${sqlStr(input.hook_event_name ?? "")}', 'codex', '${ts}', '${ts}')`;
1205
+ 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)}', '${sqlStr(input.hook_event_name ?? "")}', 'codex', '${sqlStr(PLUGIN_VERSION)}', '${ts}', '${ts}')`;
1158
1206
  try {
1159
1207
  await api.query(insertSql);
1160
1208
  } catch (e) {
@@ -697,13 +697,14 @@ var DeeplakeApi = class {
697
697
  const tables = await this.listTables();
698
698
  if (!tables.includes(tbl)) {
699
699
  log2(`table "${tbl}" not found, creating`);
700
- 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);
700
+ 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);
701
701
  log2(`table "${tbl}" created`);
702
702
  if (!tables.includes(tbl))
703
703
  this._tablesCache = [...tables, tbl];
704
704
  }
705
705
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
706
706
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
707
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
707
708
  }
708
709
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
709
710
  async ensureSessionsTable(name) {
@@ -711,13 +712,14 @@ var DeeplakeApi = class {
711
712
  const tables = await this.listTables();
712
713
  if (!tables.includes(safe)) {
713
714
  log2(`table "${safe}" not found, creating`);
714
- 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);
715
+ 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);
715
716
  log2(`table "${safe}" created`);
716
717
  if (!tables.includes(safe))
717
718
  this._tablesCache = [...tables, safe];
718
719
  }
719
720
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
720
721
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
722
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
721
723
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
722
724
  }
723
725
  /**
@@ -513,13 +513,14 @@ var DeeplakeApi = class {
513
513
  const tables = await this.listTables();
514
514
  if (!tables.includes(tbl)) {
515
515
  log2(`table "${tbl}" not found, creating`);
516
- 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);
516
+ 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);
517
517
  log2(`table "${tbl}" created`);
518
518
  if (!tables.includes(tbl))
519
519
  this._tablesCache = [...tables, tbl];
520
520
  }
521
521
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
522
522
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
523
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
523
524
  }
524
525
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
525
526
  async ensureSessionsTable(name) {
@@ -527,13 +528,14 @@ var DeeplakeApi = class {
527
528
  const tables = await this.listTables();
528
529
  if (!tables.includes(safe)) {
529
530
  log2(`table "${safe}" not found, creating`);
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 '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
531
+ 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);
531
532
  log2(`table "${safe}" created`);
532
533
  if (!tables.includes(safe))
533
534
  this._tablesCache = [...tables, safe];
534
535
  }
535
536
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
536
537
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
538
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
537
539
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
538
540
  }
539
541
  /**
@@ -53,7 +53,8 @@ var init_index_marker_store = __esm({
53
53
  });
54
54
 
55
55
  // dist/src/hooks/codex/session-start-setup.js
56
- import { join as join7 } from "node:path";
56
+ import { dirname as dirname2, join as join8 } from "node:path";
57
+ import { fileURLToPath } from "node:url";
57
58
  import { homedir as homedir4 } from "node:os";
58
59
 
59
60
  // dist/src/commands/auth.js
@@ -519,13 +520,14 @@ var DeeplakeApi = class {
519
520
  const tables = await this.listTables();
520
521
  if (!tables.includes(tbl)) {
521
522
  log2(`table "${tbl}" not found, creating`);
522
- 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);
523
+ 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);
523
524
  log2(`table "${tbl}" created`);
524
525
  if (!tables.includes(tbl))
525
526
  this._tablesCache = [...tables, tbl];
526
527
  }
527
528
  await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
528
529
  await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
530
+ await this.ensureColumn(tbl, "plugin_version", "TEXT NOT NULL DEFAULT ''");
529
531
  }
530
532
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
531
533
  async ensureSessionsTable(name) {
@@ -533,13 +535,14 @@ var DeeplakeApi = class {
533
535
  const tables = await this.listTables();
534
536
  if (!tables.includes(safe)) {
535
537
  log2(`table "${safe}" not found, creating`);
536
- 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);
538
+ 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);
537
539
  log2(`table "${safe}" created`);
538
540
  if (!tables.includes(safe))
539
541
  this._tablesCache = [...tables, safe];
540
542
  }
541
543
  await this.ensureEmbeddingColumn(safe, MESSAGE_EMBEDDING_COL);
542
544
  await this.ensureColumn(safe, "agent", "TEXT NOT NULL DEFAULT ''");
545
+ await this.ensureColumn(safe, "plugin_version", "TEXT NOT NULL DEFAULT ''");
543
546
  await this.ensureLookupIndex(safe, "path_creation_date", `("path", "creation_date")`);
544
547
  }
545
548
  /**
@@ -654,9 +657,53 @@ async function autoUpdate(creds, opts) {
654
657
  log3(`agent=${opts.agent} dispatched (pid=${pid ?? "?"}) (${Date.now() - t0}ms total)`);
655
658
  }
656
659
 
660
+ // dist/src/utils/version-check.js
661
+ import { readFileSync as readFileSync4 } from "node:fs";
662
+ import { dirname, join as join7 } from "node:path";
663
+ function getInstalledVersion(bundleDir, pluginManifestDir) {
664
+ try {
665
+ const pluginJson = join7(bundleDir, "..", pluginManifestDir, "plugin.json");
666
+ const plugin = JSON.parse(readFileSync4(pluginJson, "utf-8"));
667
+ if (plugin.version)
668
+ return plugin.version;
669
+ } catch {
670
+ }
671
+ try {
672
+ const stamp = readFileSync4(join7(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
673
+ if (stamp)
674
+ return stamp;
675
+ } catch {
676
+ }
677
+ const HIVEMIND_PKG_NAMES = /* @__PURE__ */ new Set([
678
+ "hivemind",
679
+ "hivemind-codex",
680
+ "@deeplake/hivemind",
681
+ "@deeplake/hivemind-codex",
682
+ "@activeloop/hivemind",
683
+ "@activeloop/hivemind-codex"
684
+ ]);
685
+ let dir = bundleDir;
686
+ for (let i = 0; i < 5; i++) {
687
+ const candidate = join7(dir, "package.json");
688
+ try {
689
+ const pkg = JSON.parse(readFileSync4(candidate, "utf-8"));
690
+ if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
691
+ return pkg.version;
692
+ } catch {
693
+ }
694
+ const parent = dirname(dir);
695
+ if (parent === dir)
696
+ break;
697
+ dir = parent;
698
+ }
699
+ return null;
700
+ }
701
+
657
702
  // dist/src/hooks/codex/session-start-setup.js
658
703
  var log4 = (msg) => log("codex-session-setup", msg);
659
- var { log: wikiLog } = makeWikiLogger(join7(homedir4(), ".codex", "hooks"));
704
+ var { log: wikiLog } = makeWikiLogger(join8(homedir4(), ".codex", "hooks"));
705
+ var __bundleDir = dirname2(fileURLToPath(import.meta.url));
706
+ var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".codex-plugin") ?? "";
660
707
  async function createPlaceholder(api, table, sessionId, cwd, userName, orgName, workspaceId) {
661
708
  const summaryPath = `/summaries/${userName}/${sessionId}.md`;
662
709
  const existing = await api.query(`SELECT path FROM "${table}" WHERE path = '${sqlStr(summaryPath)}' LIMIT 1`);
@@ -676,7 +723,7 @@ async function createPlaceholder(api, table, sessionId, cwd, userName, orgName,
676
723
  ""
677
724
  ].join("\n");
678
725
  const filename = `${sessionId}.md`;
679
- await api.query(`INSERT INTO "${table}" (id, path, filename, summary, author, mime_type, size_bytes, project, description, agent, creation_date, last_update_date) VALUES ('${crypto.randomUUID()}', '${sqlStr(summaryPath)}', '${sqlStr(filename)}', E'${sqlStr(content)}', '${sqlStr(userName)}', 'text/markdown', ${Buffer.byteLength(content, "utf-8")}, '${sqlStr(projectName)}', 'in progress', 'codex', '${now}', '${now}')`);
726
+ await api.query(`INSERT INTO "${table}" (id, path, filename, summary, author, mime_type, size_bytes, project, description, agent, plugin_version, creation_date, last_update_date) VALUES ('${crypto.randomUUID()}', '${sqlStr(summaryPath)}', '${sqlStr(filename)}', E'${sqlStr(content)}', '${sqlStr(userName)}', 'text/markdown', ${Buffer.byteLength(content, "utf-8")}, '${sqlStr(projectName)}', 'in progress', 'codex', '${sqlStr(PLUGIN_VERSION)}', '${now}', '${now}')`);
680
727
  wikiLog(`SessionSetup: created placeholder for ${sessionId} (${cwd})`);
681
728
  }
682
729
  async function main() {