@deeplake/hivemind 0.7.70 → 0.7.71

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 +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +10 -6
  4. package/codex/bundle/capture.js +4 -2
  5. package/codex/bundle/commands/auth-login.js +2 -0
  6. package/codex/bundle/graph-pull-worker.js +2 -0
  7. package/codex/bundle/pre-tool-use.js +27 -2
  8. package/codex/bundle/session-start-setup.js +2 -0
  9. package/codex/bundle/session-start.js +2 -0
  10. package/codex/bundle/shell/deeplake-shell.js +12 -6
  11. package/codex/bundle/skillify-worker.js +2 -0
  12. package/codex/bundle/stop.js +4 -2
  13. package/codex/bundle/wiki-worker.js +1 -1
  14. package/cursor/bundle/capture.js +4 -2
  15. package/cursor/bundle/commands/auth-login.js +2 -0
  16. package/cursor/bundle/graph-pull-worker.js +2 -0
  17. package/cursor/bundle/pre-tool-use.js +2 -0
  18. package/cursor/bundle/session-end.js +2 -2
  19. package/cursor/bundle/session-start.js +2 -0
  20. package/cursor/bundle/shell/deeplake-shell.js +12 -6
  21. package/cursor/bundle/skillify-worker.js +2 -0
  22. package/cursor/bundle/wiki-worker.js +1 -1
  23. package/hermes/bundle/capture.js +4 -2
  24. package/hermes/bundle/commands/auth-login.js +2 -0
  25. package/hermes/bundle/graph-pull-worker.js +2 -0
  26. package/hermes/bundle/pre-tool-use.js +2 -0
  27. package/hermes/bundle/session-end.js +2 -2
  28. package/hermes/bundle/session-start.js +2 -0
  29. package/hermes/bundle/shell/deeplake-shell.js +12 -6
  30. package/hermes/bundle/skillify-worker.js +2 -0
  31. package/hermes/bundle/wiki-worker.js +1 -1
  32. package/mcp/bundle/server.js +2 -0
  33. package/openclaw/dist/index.js +5 -3
  34. package/openclaw/dist/skillify-worker.js +2 -0
  35. package/openclaw/openclaw.plugin.json +1 -1
  36. package/openclaw/package.json +1 -1
  37. package/package.json +1 -1
@@ -6,18 +6,18 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
9
- "version": "0.7.70"
9
+ "version": "0.7.71"
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.70",
15
+ "version": "0.7.71",
16
16
  "source": {
17
17
  "source": "git-subdir",
18
18
  "url": "https://github.com/activeloopai/hivemind.git",
19
19
  "path": "claude-code",
20
- "sha": "b90aadd1f9d2f959a2c9800a14a4b9131bdb75d8"
20
+ "sha": "709525b85e4594fbbeff7955d566533990c762b6"
21
21
  },
22
22
  "homepage": "https://github.com/activeloopai/hivemind"
23
23
  }
@@ -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.70",
4
+ "version": "0.7.71",
5
5
  "author": {
6
6
  "name": "Activeloop",
7
7
  "url": "https://deeplake.ai"
package/bundle/cli.js CHANGED
@@ -4598,6 +4598,7 @@ var GOALS_COLUMNS = Object.freeze([
4598
4598
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
4599
4599
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
4600
4600
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
4601
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
4601
4602
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
4602
4603
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
4603
4604
  ]);
@@ -4608,6 +4609,7 @@ var KPIS_COLUMNS = Object.freeze([
4608
4609
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
4609
4610
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
4610
4611
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
4612
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
4611
4613
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
4612
4614
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
4613
4615
  ]);
@@ -11057,7 +11059,7 @@ async function goalAdd(text, agent = "manual") {
11057
11059
  const safe = sqlIdent(table);
11058
11060
  const goalId = randomUUID4();
11059
11061
  const ts = (/* @__PURE__ */ new Date()).toISOString();
11060
- await query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(cfg.userName)}', 'opened', E'${sqlStr(text)}', 1, '${sqlStr(ts)}', '${sqlStr(agent)}', '')`);
11062
+ await query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(cfg.userName)}', 'opened', E'${sqlStr(text)}', 1, '${sqlStr(ts)}', '${sqlStr(ts)}', '${sqlStr(agent)}', '')`);
11061
11063
  process.stdout.write(`${goalId}
11062
11064
  `);
11063
11065
  }
@@ -11130,10 +11132,11 @@ async function goalProgress(goalId, status) {
11130
11132
  process.stderr.write("not logged in\n");
11131
11133
  process.exit(1);
11132
11134
  }
11133
- const { query } = loadApiOrDie(cfg.goalsTableName);
11135
+ const { api, query } = loadApiOrDie(cfg.goalsTableName);
11136
+ await api.ensureGoalsTable(cfg.goalsTableName);
11134
11137
  const safe = sqlIdent(cfg.goalsTableName);
11135
11138
  const ts = (/* @__PURE__ */ new Date()).toISOString();
11136
- await query(`UPDATE "${safe}" SET status = '${sqlStr(status)}', created_at = '${sqlStr(ts)}' WHERE goal_id = '${sqlStr(goalId)}'`);
11139
+ await query(`UPDATE "${safe}" SET status = '${sqlStr(status)}', updated_at = '${sqlStr(ts)}' WHERE goal_id = '${sqlStr(goalId)}'`);
11137
11140
  process.stdout.write(`${goalId} -> ${status}
11138
11141
  `);
11139
11142
  }
@@ -11164,7 +11167,7 @@ async function kpiAdd(args) {
11164
11167
  - current: 0
11165
11168
  - unit: ${unit}`;
11166
11169
  const ts = (/* @__PURE__ */ new Date()).toISOString();
11167
- await query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(kpiId)}', E'${sqlStr(content)}', 1, '${sqlStr(ts)}', 'manual', '')`);
11170
+ await query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${randomUUID4()}', '${sqlStr(goalId)}', '${sqlStr(kpiId)}', E'${sqlStr(content)}', 1, '${sqlStr(ts)}', '${sqlStr(ts)}', 'manual', '')`);
11168
11171
  process.stdout.write(`${goalId}/${kpiId}
11169
11172
  `);
11170
11173
  }
@@ -11213,7 +11216,8 @@ async function kpiBump(goalId, kpiId, deltaStr) {
11213
11216
  process.stderr.write("not logged in\n");
11214
11217
  process.exit(1);
11215
11218
  }
11216
- const { query } = loadApiOrDie(cfg.kpisTableName);
11219
+ const { api, query } = loadApiOrDie(cfg.kpisTableName);
11220
+ await api.ensureKpisTable(cfg.kpisTableName);
11217
11221
  const safe = sqlIdent(cfg.kpisTableName);
11218
11222
  const rows = await query(`SELECT content FROM "${safe}" WHERE goal_id = '${sqlStr(goalId)}' AND kpi_id = '${sqlStr(kpiId)}' LIMIT 1`);
11219
11223
  if (rows.length === 0) {
@@ -11229,7 +11233,7 @@ async function kpiBump(goalId, kpiId, deltaStr) {
11229
11233
  process.exit(1);
11230
11234
  }
11231
11235
  const ts = (/* @__PURE__ */ new Date()).toISOString();
11232
- await query(`UPDATE "${safe}" SET content = E'${sqlStr(newContent)}', created_at = '${sqlStr(ts)}' WHERE goal_id = '${sqlStr(goalId)}' AND kpi_id = '${sqlStr(kpiId)}'`);
11236
+ await query(`UPDATE "${safe}" SET content = E'${sqlStr(newContent)}', updated_at = '${sqlStr(ts)}' WHERE goal_id = '${sqlStr(goalId)}' AND kpi_id = '${sqlStr(kpiId)}'`);
11233
11237
  process.stdout.write(`${goalId}/${kpiId} +${delta}
11234
11238
  `);
11235
11239
  }
@@ -232,6 +232,7 @@ var GOALS_COLUMNS = Object.freeze([
232
232
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
233
233
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
234
234
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
236
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
236
237
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
237
238
  ]);
@@ -242,6 +243,7 @@ var KPIS_COLUMNS = Object.freeze([
242
243
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
243
244
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
244
245
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
246
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
245
247
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
246
248
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
247
249
  ]);
@@ -1573,7 +1575,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
1573
1575
  import { dirname as dirname5, join as join14 } from "node:path";
1574
1576
 
1575
1577
  // dist/src/hooks/summary-state.js
1576
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1578
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
1577
1579
  import { homedir as homedir9 } from "node:os";
1578
1580
  import { join as join10 } from "node:path";
1579
1581
  var dlog = (msg) => log("summary-state", msg);
@@ -1844,7 +1846,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
1844
1846
  <Anything unresolved, blocked, or explicitly deferred>
1845
1847
 
1846
1848
  ## Next Steps
1847
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
1849
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
1848
1850
 
1849
1851
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
1850
1852
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -513,6 +513,7 @@ var GOALS_COLUMNS = Object.freeze([
513
513
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
514
514
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
515
515
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
517
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
517
518
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
518
519
  ]);
@@ -523,6 +524,7 @@ var KPIS_COLUMNS = Object.freeze([
523
524
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
524
525
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
525
526
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
527
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
526
528
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
527
529
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
528
530
  ]);
@@ -222,6 +222,7 @@ var GOALS_COLUMNS = Object.freeze([
222
222
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
223
223
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
224
224
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
226
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
226
227
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
227
228
  ]);
@@ -232,6 +233,7 @@ var KPIS_COLUMNS = Object.freeze([
232
233
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
233
234
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
234
235
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
236
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
237
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
236
238
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
237
239
  ]);
@@ -238,6 +238,7 @@ var GOALS_COLUMNS = Object.freeze([
238
238
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
239
239
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
240
240
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
241
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
241
242
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
242
243
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
243
244
  ]);
@@ -248,6 +249,7 @@ var KPIS_COLUMNS = Object.freeze([
248
249
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
249
250
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
250
251
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
252
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
251
253
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
252
254
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
253
255
  ]);
@@ -3117,10 +3119,33 @@ var SAFE_BUILTINS = /* @__PURE__ */ new Set([
3117
3119
  "case",
3118
3120
  "esac"
3119
3121
  ]);
3122
+ function stripHeredocBodies(cmd) {
3123
+ if (!cmd.includes("<<"))
3124
+ return cmd;
3125
+ const lines = cmd.split("\n");
3126
+ const kept = [];
3127
+ for (let i = 0; i < lines.length; i++) {
3128
+ const line = lines[i];
3129
+ kept.push(line);
3130
+ const heredoc = line.match(/<<-?\s*(['"])([A-Za-z_]\w*)\1/);
3131
+ if (!heredoc)
3132
+ continue;
3133
+ const delimiter = heredoc[2];
3134
+ const stripTabs = line.includes("<<-");
3135
+ while (i + 1 < lines.length) {
3136
+ const body = lines[++i];
3137
+ const probe = stripTabs ? body.replace(/^\t+/, "") : body;
3138
+ if (probe === delimiter)
3139
+ break;
3140
+ }
3141
+ }
3142
+ return kept.join("\n");
3143
+ }
3120
3144
  function isSafe(cmd) {
3121
- if (/\$\(|`|<\(/.test(cmd))
3145
+ const validated = stripHeredocBodies(cmd);
3146
+ if (/\$\(|`|<\(/.test(validated))
3122
3147
  return false;
3123
- const stripped = cmd.replace(/'[^']*'/g, "''").replace(/"[^"]*"/g, '""');
3148
+ const stripped = validated.replace(/'[^']*'/g, "''").replace(/"[^"]*"/g, '""');
3124
3149
  const stages = stripped.split(/\||;|&&|\|\||\n/);
3125
3150
  for (const stage of stages) {
3126
3151
  const firstToken = stage.trim().split(/\s+/)[0] ?? "";
@@ -251,6 +251,7 @@ var GOALS_COLUMNS = Object.freeze([
251
251
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
252
252
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
253
253
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
254
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
254
255
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
255
256
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
256
257
  ]);
@@ -261,6 +262,7 @@ var KPIS_COLUMNS = Object.freeze([
261
262
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
262
263
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
263
264
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
265
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
264
266
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
265
267
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
266
268
  ]);
@@ -490,6 +490,7 @@ var GOALS_COLUMNS = Object.freeze([
490
490
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
491
491
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
492
492
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
493
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
493
494
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
494
495
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
495
496
  ]);
@@ -500,6 +501,7 @@ var KPIS_COLUMNS = Object.freeze([
500
501
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
501
502
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
502
503
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
504
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
503
505
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
504
506
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
505
507
  ]);
@@ -66926,6 +66926,7 @@ var GOALS_COLUMNS = Object.freeze([
66926
66926
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66927
66927
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66928
66928
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
66930
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66930
66931
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66931
66932
  ]);
@@ -66936,6 +66937,7 @@ var KPIS_COLUMNS = Object.freeze([
66936
66937
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66937
66938
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66938
66939
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66940
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66939
66941
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66940
66942
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66941
66943
  ]);
@@ -69530,13 +69532,15 @@ var DeeplakeFs = class _DeeplakeFs {
69530
69532
  throw new Error("goalsTable not configured");
69531
69533
  const parts = decomposeGoalPath(r10.path);
69532
69534
  const safe = this.goalsTable;
69533
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69535
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69536
+ const createdAt = r10.creationDate ?? now;
69537
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69534
69538
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' LIMIT 1`);
69535
69539
  if (existing.length > 0) {
69536
- await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69540
+ await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69537
69541
  } else {
69538
69542
  const id = randomUUID2();
69539
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69543
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69540
69544
  }
69541
69545
  this.flushed.add(r10.path);
69542
69546
  }
@@ -69551,13 +69555,15 @@ var DeeplakeFs = class _DeeplakeFs {
69551
69555
  throw new Error("kpisTable not configured");
69552
69556
  const parts = decomposeKpiPath(r10.path);
69553
69557
  const safe = this.kpisTable;
69554
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69558
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69559
+ const createdAt = r10.creationDate ?? now;
69560
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69555
69561
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}' LIMIT 1`);
69556
69562
  if (existing.length > 0) {
69557
- await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69563
+ await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69558
69564
  } else {
69559
69565
  const id = randomUUID2();
69560
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69566
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69561
69567
  }
69562
69568
  this.flushed.add(r10.path);
69563
69569
  }
@@ -398,6 +398,7 @@ var GOALS_COLUMNS = Object.freeze([
398
398
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
399
399
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
400
400
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
402
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
402
403
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
403
404
  ]);
@@ -408,6 +409,7 @@ var KPIS_COLUMNS = Object.freeze([
408
409
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
409
410
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
410
411
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
412
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
411
413
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
412
414
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
413
415
  ]);
@@ -237,6 +237,7 @@ var GOALS_COLUMNS = Object.freeze([
237
237
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
238
238
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
239
239
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
240
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
240
241
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
241
242
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
242
243
  ]);
@@ -247,6 +248,7 @@ var KPIS_COLUMNS = Object.freeze([
247
248
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
248
249
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
249
250
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
251
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
250
252
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
251
253
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
252
254
  ]);
@@ -1124,7 +1126,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
1124
1126
  <Anything unresolved, blocked, or explicitly deferred>
1125
1127
 
1126
1128
  ## Next Steps
1127
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
1129
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
1128
1130
 
1129
1131
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
1130
1132
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -1578,7 +1580,7 @@ function forceSessionEndTrigger(opts) {
1578
1580
  }
1579
1581
 
1580
1582
  // dist/src/hooks/summary-state.js
1581
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync8, writeSync as writeSync2, mkdirSync as mkdirSync9, renameSync as renameSync4, existsSync as existsSync7, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1583
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync8, writeSync as writeSync2, mkdirSync as mkdirSync9, renameSync as renameSync4, existsSync as existsSync7, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync2 } from "node:fs";
1582
1584
  import { homedir as homedir9 } from "node:os";
1583
1585
  import { join as join15 } from "node:path";
1584
1586
  var dlog3 = (msg) => log("summary-state", msg);
@@ -7,7 +7,7 @@ import { dirname as dirname2, join as join6 } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
9
  // dist/src/hooks/summary-state.js
10
- import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync } from "node:fs";
10
+ import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync, statSync } from "node:fs";
11
11
  import { homedir as homedir2 } from "node:os";
12
12
  import { join as join2 } from "node:path";
13
13
 
@@ -232,6 +232,7 @@ var GOALS_COLUMNS = Object.freeze([
232
232
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
233
233
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
234
234
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
236
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
236
237
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
237
238
  ]);
@@ -242,6 +243,7 @@ var KPIS_COLUMNS = Object.freeze([
242
243
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
243
244
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
244
245
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
246
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
245
247
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
246
248
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
247
249
  ]);
@@ -1573,7 +1575,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
1573
1575
  import { dirname as dirname7, join as join20 } from "node:path";
1574
1576
 
1575
1577
  // dist/src/hooks/summary-state.js
1576
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1578
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
1577
1579
  import { homedir as homedir9 } from "node:os";
1578
1580
  import { join as join10 } from "node:path";
1579
1581
  var dlog = (msg) => log("summary-state", msg);
@@ -1844,7 +1846,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
1844
1846
  <Anything unresolved, blocked, or explicitly deferred>
1845
1847
 
1846
1848
  ## Next Steps
1847
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
1849
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
1848
1850
 
1849
1851
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
1850
1852
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -513,6 +513,7 @@ var GOALS_COLUMNS = Object.freeze([
513
513
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
514
514
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
515
515
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
517
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
517
518
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
518
519
  ]);
@@ -523,6 +524,7 @@ var KPIS_COLUMNS = Object.freeze([
523
524
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
524
525
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
525
526
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
527
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
526
528
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
527
529
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
528
530
  ]);
@@ -222,6 +222,7 @@ var GOALS_COLUMNS = Object.freeze([
222
222
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
223
223
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
224
224
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
226
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
226
227
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
227
228
  ]);
@@ -232,6 +233,7 @@ var KPIS_COLUMNS = Object.freeze([
232
233
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
233
234
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
234
235
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
236
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
237
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
236
238
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
237
239
  ]);
@@ -231,6 +231,7 @@ var GOALS_COLUMNS = Object.freeze([
231
231
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
232
232
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
233
233
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
235
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
235
236
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
236
237
  ]);
@@ -241,6 +242,7 @@ var KPIS_COLUMNS = Object.freeze([
241
242
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
242
243
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
243
244
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
245
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
244
246
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
245
247
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
246
248
  ]);
@@ -83,7 +83,7 @@ function loadConfig() {
83
83
  }
84
84
 
85
85
  // dist/src/hooks/summary-state.js
86
- import { readFileSync as readFileSync2, writeFileSync, writeSync, mkdirSync, renameSync, existsSync as existsSync2, unlinkSync, openSync, closeSync } from "node:fs";
86
+ import { readFileSync as readFileSync2, writeFileSync, writeSync, mkdirSync, renameSync, existsSync as existsSync2, unlinkSync, openSync, closeSync, statSync } from "node:fs";
87
87
  import { homedir as homedir3 } from "node:os";
88
88
  import { join as join3 } from "node:path";
89
89
  var dlog = (msg) => log("summary-state", msg);
@@ -269,7 +269,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
269
269
  <Anything unresolved, blocked, or explicitly deferred>
270
270
 
271
271
  ## Next Steps
272
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
272
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
273
273
 
274
274
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
275
275
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -305,6 +305,7 @@ var GOALS_COLUMNS = Object.freeze([
305
305
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
306
306
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
307
307
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
308
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
308
309
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
309
310
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
310
311
  ]);
@@ -315,6 +316,7 @@ var KPIS_COLUMNS = Object.freeze([
315
316
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
316
317
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
317
318
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
319
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
318
320
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
319
321
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
320
322
  ]);
@@ -66926,6 +66926,7 @@ var GOALS_COLUMNS = Object.freeze([
66926
66926
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66927
66927
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66928
66928
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
66930
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66930
66931
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66931
66932
  ]);
@@ -66936,6 +66937,7 @@ var KPIS_COLUMNS = Object.freeze([
66936
66937
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66937
66938
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66938
66939
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66940
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66939
66941
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66940
66942
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66941
66943
  ]);
@@ -69530,13 +69532,15 @@ var DeeplakeFs = class _DeeplakeFs {
69530
69532
  throw new Error("goalsTable not configured");
69531
69533
  const parts = decomposeGoalPath(r10.path);
69532
69534
  const safe = this.goalsTable;
69533
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69535
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69536
+ const createdAt = r10.creationDate ?? now;
69537
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69534
69538
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' LIMIT 1`);
69535
69539
  if (existing.length > 0) {
69536
- await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69540
+ await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69537
69541
  } else {
69538
69542
  const id = randomUUID2();
69539
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69543
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69540
69544
  }
69541
69545
  this.flushed.add(r10.path);
69542
69546
  }
@@ -69551,13 +69555,15 @@ var DeeplakeFs = class _DeeplakeFs {
69551
69555
  throw new Error("kpisTable not configured");
69552
69556
  const parts = decomposeKpiPath(r10.path);
69553
69557
  const safe = this.kpisTable;
69554
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69558
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69559
+ const createdAt = r10.creationDate ?? now;
69560
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69555
69561
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}' LIMIT 1`);
69556
69562
  if (existing.length > 0) {
69557
- await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69563
+ await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69558
69564
  } else {
69559
69565
  const id = randomUUID2();
69560
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69566
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69561
69567
  }
69562
69568
  this.flushed.add(r10.path);
69563
69569
  }
@@ -398,6 +398,7 @@ var GOALS_COLUMNS = Object.freeze([
398
398
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
399
399
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
400
400
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
402
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
402
403
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
403
404
  ]);
@@ -408,6 +409,7 @@ var KPIS_COLUMNS = Object.freeze([
408
409
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
409
410
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
410
411
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
412
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
411
413
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
412
414
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
413
415
  ]);
@@ -7,7 +7,7 @@ import { dirname as dirname2, join as join6 } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
9
  // dist/src/hooks/summary-state.js
10
- import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync } from "node:fs";
10
+ import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync, statSync } from "node:fs";
11
11
  import { homedir as homedir2 } from "node:os";
12
12
  import { join as join2 } from "node:path";
13
13
 
@@ -231,6 +231,7 @@ var GOALS_COLUMNS = Object.freeze([
231
231
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
232
232
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
233
233
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
235
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
235
236
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
236
237
  ]);
@@ -241,6 +242,7 @@ var KPIS_COLUMNS = Object.freeze([
241
242
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
242
243
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
243
244
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
245
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
244
246
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
245
247
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
246
248
  ]);
@@ -1572,7 +1574,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
1572
1574
  import { dirname as dirname7, join as join20 } from "node:path";
1573
1575
 
1574
1576
  // dist/src/hooks/summary-state.js
1575
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1577
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
1576
1578
  import { homedir as homedir9 } from "node:os";
1577
1579
  import { join as join10 } from "node:path";
1578
1580
  var dlog = (msg) => log("summary-state", msg);
@@ -1843,7 +1845,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
1843
1845
  <Anything unresolved, blocked, or explicitly deferred>
1844
1846
 
1845
1847
  ## Next Steps
1846
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
1848
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
1847
1849
 
1848
1850
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
1849
1851
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -513,6 +513,7 @@ var GOALS_COLUMNS = Object.freeze([
513
513
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
514
514
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
515
515
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
516
517
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
517
518
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
518
519
  ]);
@@ -523,6 +524,7 @@ var KPIS_COLUMNS = Object.freeze([
523
524
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
524
525
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
525
526
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
527
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
526
528
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
527
529
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
528
530
  ]);
@@ -222,6 +222,7 @@ var GOALS_COLUMNS = Object.freeze([
222
222
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
223
223
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
224
224
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
225
226
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
226
227
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
227
228
  ]);
@@ -232,6 +233,7 @@ var KPIS_COLUMNS = Object.freeze([
232
233
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
233
234
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
234
235
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
236
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
235
237
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
236
238
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
237
239
  ]);
@@ -231,6 +231,7 @@ var GOALS_COLUMNS = Object.freeze([
231
231
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
232
232
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
233
233
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
234
235
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
235
236
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
236
237
  ]);
@@ -241,6 +242,7 @@ var KPIS_COLUMNS = Object.freeze([
241
242
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
242
243
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
243
244
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
245
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
244
246
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
245
247
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
246
248
  ]);
@@ -81,7 +81,7 @@ function loadConfig() {
81
81
  }
82
82
 
83
83
  // dist/src/hooks/summary-state.js
84
- import { readFileSync as readFileSync2, writeFileSync, writeSync, mkdirSync, renameSync, existsSync as existsSync2, unlinkSync, openSync, closeSync } from "node:fs";
84
+ import { readFileSync as readFileSync2, writeFileSync, writeSync, mkdirSync, renameSync, existsSync as existsSync2, unlinkSync, openSync, closeSync, statSync } from "node:fs";
85
85
  import { homedir as homedir3 } from "node:os";
86
86
  import { join as join3 } from "node:path";
87
87
  var dlog = (msg) => log("summary-state", msg);
@@ -267,7 +267,7 @@ Format: **entity** (type) \u2014 what was done with it, its current state>
267
267
  <Anything unresolved, blocked, or explicitly deferred>
268
268
 
269
269
  ## Next Steps
270
- <The single concrete next action to resume with, as one imperative line (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). If the session reached a clean stopping point with nothing pending, write exactly: none>
270
+ <Default to writing exactly: none. Most sessions are DONE when they end \u2014 do not invent a next step just to fill this section. Only name one when the session left GENUINELY SUBSTANTIVE, non-obvious work that a knowledgeable engineer returning later would actually need flagged. Make a real judgment: is there unfinished work truly WORTH resuming? If not, write: none. Write none when the work reached a natural stopping point, is complete, only trivial/obvious follow-ups remain, the "next step" is just continuing an open-ended exploration, or the only thing left is administrative wrap-up (committing, pushing, opening/merging a PR, deploying, monitoring CI) \u2014 treat all such wrap-up as ALREADY DONE. When a next step IS warranted, write a single concrete imperative line for the substantive work (e.g. "Wire the resume-brief Next Steps fallback and run the tests"). Administrative actions qualify ONLY when the session's core purpose itself was that release/ops task.>
271
271
 
272
272
  IMPORTANT: Be exhaustive. Extract EVERY entity, decision, and fact.
273
273
  PRIVACY: Never include absolute filesystem paths in the summary.
@@ -304,6 +304,7 @@ var GOALS_COLUMNS = Object.freeze([
304
304
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
305
305
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
306
306
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
307
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
307
308
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
308
309
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
309
310
  ]);
@@ -314,6 +315,7 @@ var KPIS_COLUMNS = Object.freeze([
314
315
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
315
316
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
316
317
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
318
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
317
319
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
318
320
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
319
321
  ]);
@@ -66926,6 +66926,7 @@ var GOALS_COLUMNS = Object.freeze([
66926
66926
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66927
66927
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66928
66928
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66929
66930
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66930
66931
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66931
66932
  ]);
@@ -66936,6 +66937,7 @@ var KPIS_COLUMNS = Object.freeze([
66936
66937
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
66937
66938
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
66938
66939
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
66940
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
66939
66941
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
66940
66942
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
66941
66943
  ]);
@@ -69530,13 +69532,15 @@ var DeeplakeFs = class _DeeplakeFs {
69530
69532
  throw new Error("goalsTable not configured");
69531
69533
  const parts = decomposeGoalPath(r10.path);
69532
69534
  const safe = this.goalsTable;
69533
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69535
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69536
+ const createdAt = r10.creationDate ?? now;
69537
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69534
69538
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' LIMIT 1`);
69535
69539
  if (existing.length > 0) {
69536
- await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69540
+ await this.client.query(`UPDATE "${safe}" SET owner = '${sqlStr(parts.owner)}', status = '${sqlStr(parts.status)}', content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}'`);
69537
69541
  } else {
69538
69542
  const id = randomUUID2();
69539
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69543
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.owner)}', '${sqlStr(parts.status)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69540
69544
  }
69541
69545
  this.flushed.add(r10.path);
69542
69546
  }
@@ -69551,13 +69555,15 @@ var DeeplakeFs = class _DeeplakeFs {
69551
69555
  throw new Error("kpisTable not configured");
69552
69556
  const parts = decomposeKpiPath(r10.path);
69553
69557
  const safe = this.kpisTable;
69554
- const ts3 = r10.lastUpdateDate ?? r10.creationDate ?? (/* @__PURE__ */ new Date()).toISOString();
69558
+ const now = (/* @__PURE__ */ new Date()).toISOString();
69559
+ const createdAt = r10.creationDate ?? now;
69560
+ const updatedAt = r10.lastUpdateDate ?? createdAt;
69555
69561
  const existing = await this.client.query(`SELECT id FROM "${safe}" WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}' LIMIT 1`);
69556
69562
  if (existing.length > 0) {
69557
- await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', created_at = '${sqlStr(ts3)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69563
+ await this.client.query(`UPDATE "${safe}" SET content = E'${sqlStr(r10.contentText)}', updated_at = '${sqlStr(updatedAt)}' WHERE goal_id = '${sqlStr(parts.goal_id)}' AND kpi_id = '${sqlStr(parts.kpi_id)}'`);
69558
69564
  } else {
69559
69565
  const id = randomUUID2();
69560
- await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(ts3)}', 'manual', '')`);
69566
+ await this.client.query(`INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${id}', '${sqlStr(parts.goal_id)}', '${sqlStr(parts.kpi_id)}', E'${sqlStr(r10.contentText)}', 1, '${sqlStr(createdAt)}', '${sqlStr(updatedAt)}', 'manual', '')`);
69561
69567
  }
69562
69568
  this.flushed.add(r10.path);
69563
69569
  }
@@ -398,6 +398,7 @@ var GOALS_COLUMNS = Object.freeze([
398
398
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
399
399
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
400
400
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
401
402
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
402
403
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
403
404
  ]);
@@ -408,6 +409,7 @@ var KPIS_COLUMNS = Object.freeze([
408
409
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
409
410
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
410
411
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
412
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
411
413
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
412
414
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
413
415
  ]);
@@ -7,7 +7,7 @@ import { dirname as dirname2, join as join6 } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
9
  // dist/src/hooks/summary-state.js
10
- import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync } from "node:fs";
10
+ import { readFileSync, writeFileSync, writeSync, mkdirSync, renameSync, existsSync, unlinkSync, openSync, closeSync, statSync } from "node:fs";
11
11
  import { homedir as homedir2 } from "node:os";
12
12
  import { join as join2 } from "node:path";
13
13
 
@@ -23455,6 +23455,7 @@ var GOALS_COLUMNS = Object.freeze([
23455
23455
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
23456
23456
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
23457
23457
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
23458
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
23458
23459
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
23459
23460
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
23460
23461
  ]);
@@ -23465,6 +23466,7 @@ var KPIS_COLUMNS = Object.freeze([
23465
23466
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
23466
23467
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
23467
23468
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
23469
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
23468
23470
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
23469
23471
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
23470
23472
  ]);
@@ -273,6 +273,7 @@ var GOALS_COLUMNS = Object.freeze([
273
273
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
274
274
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
275
275
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
276
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
276
277
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
277
278
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
278
279
  ]);
@@ -283,6 +284,7 @@ var KPIS_COLUMNS = Object.freeze([
283
284
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
284
285
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
285
286
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
287
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
286
288
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
287
289
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
288
290
  ]);
@@ -1799,7 +1801,7 @@ function extractLatestVersion(body) {
1799
1801
  return typeof v === "string" && v.length > 0 ? v : null;
1800
1802
  }
1801
1803
  function getInstalledVersion() {
1802
- return "0.7.70".length > 0 ? "0.7.70" : null;
1804
+ return "0.7.71".length > 0 ? "0.7.71" : null;
1803
1805
  }
1804
1806
  function isNewer(latest, current) {
1805
1807
  const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
@@ -2488,7 +2490,7 @@ ${body.slice(0, 500)}`;
2488
2490
  const ts = (/* @__PURE__ */ new Date()).toISOString();
2489
2491
  const safe = goalsTable.replace(/[^A-Za-z0-9_]/g, "");
2490
2492
  await dl.query(
2491
- `INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, agent, plugin_version) VALUES ('${crypto.randomUUID()}', '${sqlStr(goalId)}', '${sqlStr(owner)}', 'opened', E'${sqlStr(params.text)}', 1, '${sqlStr(ts)}', 'openclaw', '')`
2493
+ `INSERT INTO "${safe}" (id, goal_id, owner, status, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${crypto.randomUUID()}', '${sqlStr(goalId)}', '${sqlStr(owner)}', 'opened', E'${sqlStr(params.text)}', 1, '${sqlStr(ts)}', '${sqlStr(ts)}', 'openclaw', '')`
2492
2494
  );
2493
2495
  pluginApi.logger.info?.(`hivemind_goal_add \u2192 ${goalId}`);
2494
2496
  return { content: [{ type: "text", text: `Goal created.
@@ -2536,7 +2538,7 @@ text: ${params.text}` }], details: { goal_id: goalId } };
2536
2538
  const ts = (/* @__PURE__ */ new Date()).toISOString();
2537
2539
  const safe = kpisTable.replace(/[^A-Za-z0-9_]/g, "");
2538
2540
  await dl.query(
2539
- `INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, agent, plugin_version) VALUES ('${crypto.randomUUID()}', '${sqlStr(params.goal_id)}', '${sqlStr(params.kpi_id)}', E'${sqlStr(content)}', 1, '${sqlStr(ts)}', 'openclaw', '')`
2541
+ `INSERT INTO "${safe}" (id, goal_id, kpi_id, content, version, created_at, updated_at, agent, plugin_version) VALUES ('${crypto.randomUUID()}', '${sqlStr(params.goal_id)}', '${sqlStr(params.kpi_id)}', E'${sqlStr(content)}', 1, '${sqlStr(ts)}', '${sqlStr(ts)}', 'openclaw', '')`
2540
2542
  );
2541
2543
  pluginApi.logger.info?.(`hivemind_kpi_add \u2192 ${params.goal_id}/${params.kpi_id}`);
2542
2544
  return { content: [{ type: "text", text: `KPI added.
@@ -399,6 +399,7 @@ var GOALS_COLUMNS = Object.freeze([
399
399
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
400
400
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
401
401
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
402
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
402
403
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
403
404
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
404
405
  ]);
@@ -409,6 +410,7 @@ var KPIS_COLUMNS = Object.freeze([
409
410
  { name: "content", sql: "TEXT NOT NULL DEFAULT ''" },
410
411
  { name: "version", sql: "BIGINT NOT NULL DEFAULT 1" },
411
412
  { name: "created_at", sql: "TEXT NOT NULL DEFAULT ''" },
413
+ { name: "updated_at", sql: "TEXT NOT NULL DEFAULT ''" },
412
414
  { name: "agent", sql: "TEXT NOT NULL DEFAULT 'manual'" },
413
415
  { name: "plugin_version", sql: "TEXT NOT NULL DEFAULT ''" }
414
416
  ]);
@@ -54,5 +54,5 @@
54
54
  }
55
55
  }
56
56
  },
57
- "version": "0.7.70"
57
+ "version": "0.7.71"
58
58
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hivemind",
3
- "version": "0.7.70",
3
+ "version": "0.7.71",
4
4
  "type": "module",
5
5
  "description": "Hivemind — cloud-backed persistent shared memory for AI agents, powered by DeepLake",
6
6
  "license": "Apache-2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeplake/hivemind",
3
- "version": "0.7.70",
3
+ "version": "0.7.71",
4
4
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
5
5
  "type": "module",
6
6
  "repository": {