@askexenow/exe-os 0.8.83 → 0.8.85

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 (95) hide show
  1. package/dist/bin/backfill-conversations.js +746 -595
  2. package/dist/bin/backfill-responses.js +745 -594
  3. package/dist/bin/backfill-vectors.js +312 -226
  4. package/dist/bin/cleanup-stale-review-tasks.js +97 -2
  5. package/dist/bin/cli.js +14350 -12518
  6. package/dist/bin/exe-agent.js +97 -88
  7. package/dist/bin/exe-assign.js +1003 -854
  8. package/dist/bin/exe-boot.js +1257 -320
  9. package/dist/bin/exe-call.js +10 -0
  10. package/dist/bin/exe-cloud.js +29 -6
  11. package/dist/bin/exe-dispatch.js +210 -34
  12. package/dist/bin/exe-doctor.js +403 -6
  13. package/dist/bin/exe-export-behaviors.js +175 -72
  14. package/dist/bin/exe-forget.js +97 -2
  15. package/dist/bin/exe-gateway.js +550 -171
  16. package/dist/bin/exe-healthcheck.js +1 -0
  17. package/dist/bin/exe-heartbeat.js +100 -5
  18. package/dist/bin/exe-kill.js +175 -72
  19. package/dist/bin/exe-launch-agent.js +189 -76
  20. package/dist/bin/exe-link.js +902 -80
  21. package/dist/bin/exe-new-employee.js +38 -8
  22. package/dist/bin/exe-pending-messages.js +96 -2
  23. package/dist/bin/exe-pending-notifications.js +97 -2
  24. package/dist/bin/exe-pending-reviews.js +98 -3
  25. package/dist/bin/exe-rename.js +564 -23
  26. package/dist/bin/exe-review.js +231 -73
  27. package/dist/bin/exe-search.js +989 -226
  28. package/dist/bin/exe-session-cleanup.js +4806 -1665
  29. package/dist/bin/exe-settings.js +20 -5
  30. package/dist/bin/exe-status.js +97 -2
  31. package/dist/bin/exe-team.js +97 -2
  32. package/dist/bin/git-sweep.js +899 -207
  33. package/dist/bin/graph-backfill.js +175 -72
  34. package/dist/bin/graph-export.js +175 -72
  35. package/dist/bin/install.js +38 -7
  36. package/dist/bin/list-providers.js +1 -0
  37. package/dist/bin/scan-tasks.js +904 -211
  38. package/dist/bin/setup.js +867 -268
  39. package/dist/bin/shard-migrate.js +175 -72
  40. package/dist/bin/update.js +1 -0
  41. package/dist/bin/wiki-sync.js +175 -72
  42. package/dist/gateway/index.js +548 -166
  43. package/dist/hooks/bug-report-worker.js +208 -23
  44. package/dist/hooks/commit-complete.js +897 -205
  45. package/dist/hooks/error-recall.js +988 -226
  46. package/dist/hooks/ingest-worker.js +1638 -1194
  47. package/dist/hooks/ingest.js +3 -0
  48. package/dist/hooks/instructions-loaded.js +707 -97
  49. package/dist/hooks/notification.js +699 -89
  50. package/dist/hooks/post-compact.js +714 -104
  51. package/dist/hooks/pre-compact.js +897 -205
  52. package/dist/hooks/pre-tool-use.js +742 -123
  53. package/dist/hooks/prompt-ingest-worker.js +242 -101
  54. package/dist/hooks/prompt-submit.js +995 -233
  55. package/dist/hooks/response-ingest-worker.js +242 -101
  56. package/dist/hooks/session-end.js +3941 -400
  57. package/dist/hooks/session-start.js +1001 -226
  58. package/dist/hooks/stop.js +725 -115
  59. package/dist/hooks/subagent-stop.js +714 -104
  60. package/dist/hooks/summary-worker.js +1964 -1330
  61. package/dist/index.js +1651 -1053
  62. package/dist/lib/cloud-sync.js +907 -86
  63. package/dist/lib/consolidation.js +2 -1
  64. package/dist/lib/database.js +642 -87
  65. package/dist/lib/db-daemon-client.js +503 -0
  66. package/dist/lib/device-registry.js +547 -7
  67. package/dist/lib/embedder.js +14 -28
  68. package/dist/lib/employee-templates.js +84 -74
  69. package/dist/lib/employees.js +9 -0
  70. package/dist/lib/exe-daemon-client.js +16 -29
  71. package/dist/lib/exe-daemon.js +1955 -922
  72. package/dist/lib/hybrid-search.js +988 -226
  73. package/dist/lib/identity.js +87 -67
  74. package/dist/lib/keychain.js +9 -1
  75. package/dist/lib/messaging.js +8 -1
  76. package/dist/lib/reminders.js +91 -74
  77. package/dist/lib/schedules.js +96 -2
  78. package/dist/lib/skill-learning.js +103 -85
  79. package/dist/lib/store.js +234 -73
  80. package/dist/lib/tasks.js +111 -22
  81. package/dist/lib/tmux-routing.js +120 -31
  82. package/dist/lib/token-spend.js +273 -0
  83. package/dist/lib/ws-client.js +11 -0
  84. package/dist/mcp/server.js +5222 -475
  85. package/dist/mcp/tools/complete-reminder.js +94 -77
  86. package/dist/mcp/tools/create-reminder.js +94 -77
  87. package/dist/mcp/tools/create-task.js +120 -22
  88. package/dist/mcp/tools/deactivate-behavior.js +95 -77
  89. package/dist/mcp/tools/list-reminders.js +94 -77
  90. package/dist/mcp/tools/list-tasks.js +31 -1
  91. package/dist/mcp/tools/send-message.js +8 -1
  92. package/dist/mcp/tools/update-task.js +39 -10
  93. package/dist/runtime/index.js +911 -219
  94. package/dist/tui/App.js +997 -295
  95. package/package.json +6 -1
@@ -11,6 +11,7 @@ import { realpathSync } from "fs";
11
11
  import { fileURLToPath } from "url";
12
12
  function isMainModule(importMetaUrl) {
13
13
  if (process.argv[1] == null) return false;
14
+ if (process.argv[1].includes("mcp/server")) return false;
14
15
  try {
15
16
  const scriptPath = realpathSync(process.argv[1]);
16
17
  const modulePath = realpathSync(fileURLToPath(importMetaUrl));
@@ -335,6 +335,12 @@ function getClient() {
335
335
  if (!_resilientClient) {
336
336
  throw new Error("Database client not initialized. Call initDatabase() first.");
337
337
  }
338
+ if (process.env.EXE_IS_DAEMON === "1") {
339
+ return _resilientClient;
340
+ }
341
+ if (_daemonClient && _daemonClient._isDaemonActive()) {
342
+ return _daemonClient;
343
+ }
338
344
  return _resilientClient;
339
345
  }
340
346
  function getRawClient() {
@@ -823,6 +829,12 @@ async function ensureSchema() {
823
829
  } catch {
824
830
  }
825
831
  }
832
+ try {
833
+ await client.execute(
834
+ `CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
835
+ );
836
+ } catch {
837
+ }
826
838
  await client.executeMultiple(`
827
839
  CREATE TABLE IF NOT EXISTS entities (
828
840
  id TEXT PRIMARY KEY,
@@ -875,7 +887,30 @@ async function ensureSchema() {
875
887
  entity_id TEXT NOT NULL,
876
888
  PRIMARY KEY (hyperedge_id, entity_id)
877
889
  );
890
+
891
+ CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
892
+ name,
893
+ content=entities,
894
+ content_rowid=rowid
895
+ );
896
+
897
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ai AFTER INSERT ON entities BEGIN
898
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
899
+ END;
900
+
901
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ad AFTER DELETE ON entities BEGIN
902
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
903
+ END;
904
+
905
+ CREATE TRIGGER IF NOT EXISTS entities_fts_au AFTER UPDATE ON entities BEGIN
906
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
907
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
908
+ END;
878
909
  `);
910
+ try {
911
+ await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
912
+ } catch {
913
+ }
879
914
  await client.executeMultiple(`
880
915
  CREATE TABLE IF NOT EXISTS entity_aliases (
881
916
  alias TEXT NOT NULL PRIMARY KEY,
@@ -1056,6 +1091,33 @@ async function ensureSchema() {
1056
1091
  CREATE INDEX IF NOT EXISTS idx_conversations_channel
1057
1092
  ON conversations(channel_id);
1058
1093
  `);
1094
+ await client.executeMultiple(`
1095
+ CREATE TABLE IF NOT EXISTS session_agent_map (
1096
+ session_uuid TEXT PRIMARY KEY,
1097
+ agent_id TEXT NOT NULL,
1098
+ session_name TEXT,
1099
+ task_id TEXT,
1100
+ project_name TEXT,
1101
+ started_at TEXT NOT NULL
1102
+ );
1103
+
1104
+ CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1105
+ ON session_agent_map(agent_id);
1106
+ `);
1107
+ try {
1108
+ const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1109
+ if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
1110
+ await client.execute({
1111
+ sql: `INSERT OR IGNORE INTO session_agent_map (session_uuid, agent_id, session_name, started_at)
1112
+ SELECT session_id, agent_id, '', MIN(timestamp)
1113
+ FROM memories
1114
+ WHERE session_id IS NOT NULL AND session_id != '' AND agent_id IS NOT NULL AND agent_id != ''
1115
+ GROUP BY session_id, agent_id`,
1116
+ args: []
1117
+ });
1118
+ }
1119
+ } catch {
1120
+ }
1059
1121
  try {
1060
1122
  await client.execute({
1061
1123
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -1189,8 +1251,30 @@ async function ensureSchema() {
1189
1251
  });
1190
1252
  } catch {
1191
1253
  }
1254
+ for (const col of [
1255
+ "ALTER TABLE memories ADD COLUMN intent TEXT",
1256
+ "ALTER TABLE memories ADD COLUMN outcome TEXT",
1257
+ "ALTER TABLE memories ADD COLUMN domain TEXT",
1258
+ "ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
1259
+ "ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
1260
+ "ALTER TABLE memories ADD COLUMN chain_position TEXT",
1261
+ "ALTER TABLE memories ADD COLUMN review_status TEXT",
1262
+ "ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
1263
+ "ALTER TABLE memories ADD COLUMN file_paths TEXT",
1264
+ "ALTER TABLE memories ADD COLUMN commit_hash TEXT",
1265
+ "ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
1266
+ "ALTER TABLE memories ADD COLUMN token_cost REAL",
1267
+ "ALTER TABLE memories ADD COLUMN audience TEXT",
1268
+ "ALTER TABLE memories ADD COLUMN language_type TEXT",
1269
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
1270
+ ]) {
1271
+ try {
1272
+ await client.execute(col);
1273
+ } catch {
1274
+ }
1275
+ }
1192
1276
  }
1193
- var _client, _resilientClient, initTurso;
1277
+ var _client, _resilientClient, _daemonClient, initTurso;
1194
1278
  var init_database = __esm({
1195
1279
  "src/lib/database.ts"() {
1196
1280
  "use strict";
@@ -1198,6 +1282,7 @@ var init_database = __esm({
1198
1282
  init_employees();
1199
1283
  _client = null;
1200
1284
  _resilientClient = null;
1285
+ _daemonClient = null;
1201
1286
  initTurso = initDatabase;
1202
1287
  }
1203
1288
  });
@@ -1998,7 +2083,7 @@ async function listPendingReviews(limit, sessionScope) {
1998
2083
  const result2 = await client.execute({
1999
2084
  sql: `SELECT title, assigned_to, project_name FROM tasks
2000
2085
  WHERE status = 'needs_review'
2001
- AND (session_scope = ? OR session_scope IS NULL)
2086
+ AND session_scope = ?
2002
2087
  ORDER BY priority ASC, created_at DESC LIMIT ?`,
2003
2088
  args: [sessionScope, limit]
2004
2089
  });
@@ -2050,12 +2135,13 @@ var init_task_scope = __esm({
2050
2135
  });
2051
2136
 
2052
2137
  // src/bin/exe-heartbeat.ts
2053
- import { createHash } from "crypto";
2138
+ import { createHash as createHash2 } from "crypto";
2054
2139
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
2055
2140
  import os8 from "os";
2056
2141
  import path12 from "path";
2057
2142
 
2058
2143
  // src/lib/store.ts
2144
+ import { createHash } from "crypto";
2059
2145
  init_database();
2060
2146
 
2061
2147
  // src/lib/keychain.ts
@@ -2091,12 +2177,20 @@ async function getMasterKey() {
2091
2177
  }
2092
2178
  const keyPath = getKeyPath();
2093
2179
  if (!existsSync3(keyPath)) {
2180
+ process.stderr.write(
2181
+ `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
2182
+ `
2183
+ );
2094
2184
  return null;
2095
2185
  }
2096
2186
  try {
2097
2187
  const content = await readFile3(keyPath, "utf-8");
2098
2188
  return Buffer.from(content.trim(), "base64");
2099
- } catch {
2189
+ } catch (err) {
2190
+ process.stderr.write(
2191
+ `[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
2192
+ `
2193
+ );
2100
2194
  return null;
2101
2195
  }
2102
2196
  }
@@ -2189,6 +2283,7 @@ import { realpathSync } from "fs";
2189
2283
  import { fileURLToPath } from "url";
2190
2284
  function isMainModule(importMetaUrl) {
2191
2285
  if (process.argv[1] == null) return false;
2286
+ if (process.argv[1].includes("mcp/server")) return false;
2192
2287
  try {
2193
2288
  const scriptPath = realpathSync(process.argv[1]);
2194
2289
  const modulePath = realpathSync(fileURLToPath(importMetaUrl));
@@ -2243,7 +2338,7 @@ function writeMarker(marker) {
2243
2338
  }
2244
2339
  }
2245
2340
  function hashOutput(text) {
2246
- return createHash("sha256").update(text).digest("hex");
2341
+ return createHash2("sha256").update(text).digest("hex");
2247
2342
  }
2248
2343
  async function queryPendingReviews() {
2249
2344
  let sessionScope;
@@ -305,6 +305,12 @@ function getClient() {
305
305
  if (!_resilientClient) {
306
306
  throw new Error("Database client not initialized. Call initDatabase() first.");
307
307
  }
308
+ if (process.env.EXE_IS_DAEMON === "1") {
309
+ return _resilientClient;
310
+ }
311
+ if (_daemonClient && _daemonClient._isDaemonActive()) {
312
+ return _daemonClient;
313
+ }
308
314
  return _resilientClient;
309
315
  }
310
316
  function getRawClient() {
@@ -793,6 +799,12 @@ async function ensureSchema() {
793
799
  } catch {
794
800
  }
795
801
  }
802
+ try {
803
+ await client.execute(
804
+ `CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
805
+ );
806
+ } catch {
807
+ }
796
808
  await client.executeMultiple(`
797
809
  CREATE TABLE IF NOT EXISTS entities (
798
810
  id TEXT PRIMARY KEY,
@@ -845,7 +857,30 @@ async function ensureSchema() {
845
857
  entity_id TEXT NOT NULL,
846
858
  PRIMARY KEY (hyperedge_id, entity_id)
847
859
  );
860
+
861
+ CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
862
+ name,
863
+ content=entities,
864
+ content_rowid=rowid
865
+ );
866
+
867
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ai AFTER INSERT ON entities BEGIN
868
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
869
+ END;
870
+
871
+ CREATE TRIGGER IF NOT EXISTS entities_fts_ad AFTER DELETE ON entities BEGIN
872
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
873
+ END;
874
+
875
+ CREATE TRIGGER IF NOT EXISTS entities_fts_au AFTER UPDATE ON entities BEGIN
876
+ INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
877
+ INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
878
+ END;
848
879
  `);
880
+ try {
881
+ await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
882
+ } catch {
883
+ }
849
884
  await client.executeMultiple(`
850
885
  CREATE TABLE IF NOT EXISTS entity_aliases (
851
886
  alias TEXT NOT NULL PRIMARY KEY,
@@ -1026,6 +1061,33 @@ async function ensureSchema() {
1026
1061
  CREATE INDEX IF NOT EXISTS idx_conversations_channel
1027
1062
  ON conversations(channel_id);
1028
1063
  `);
1064
+ await client.executeMultiple(`
1065
+ CREATE TABLE IF NOT EXISTS session_agent_map (
1066
+ session_uuid TEXT PRIMARY KEY,
1067
+ agent_id TEXT NOT NULL,
1068
+ session_name TEXT,
1069
+ task_id TEXT,
1070
+ project_name TEXT,
1071
+ started_at TEXT NOT NULL
1072
+ );
1073
+
1074
+ CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1075
+ ON session_agent_map(agent_id);
1076
+ `);
1077
+ try {
1078
+ const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1079
+ if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
1080
+ await client.execute({
1081
+ sql: `INSERT OR IGNORE INTO session_agent_map (session_uuid, agent_id, session_name, started_at)
1082
+ SELECT session_id, agent_id, '', MIN(timestamp)
1083
+ FROM memories
1084
+ WHERE session_id IS NOT NULL AND session_id != '' AND agent_id IS NOT NULL AND agent_id != ''
1085
+ GROUP BY session_id, agent_id`,
1086
+ args: []
1087
+ });
1088
+ }
1089
+ } catch {
1090
+ }
1029
1091
  try {
1030
1092
  await client.execute({
1031
1093
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -1159,15 +1221,41 @@ async function ensureSchema() {
1159
1221
  });
1160
1222
  } catch {
1161
1223
  }
1224
+ for (const col of [
1225
+ "ALTER TABLE memories ADD COLUMN intent TEXT",
1226
+ "ALTER TABLE memories ADD COLUMN outcome TEXT",
1227
+ "ALTER TABLE memories ADD COLUMN domain TEXT",
1228
+ "ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
1229
+ "ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
1230
+ "ALTER TABLE memories ADD COLUMN chain_position TEXT",
1231
+ "ALTER TABLE memories ADD COLUMN review_status TEXT",
1232
+ "ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
1233
+ "ALTER TABLE memories ADD COLUMN file_paths TEXT",
1234
+ "ALTER TABLE memories ADD COLUMN commit_hash TEXT",
1235
+ "ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
1236
+ "ALTER TABLE memories ADD COLUMN token_cost REAL",
1237
+ "ALTER TABLE memories ADD COLUMN audience TEXT",
1238
+ "ALTER TABLE memories ADD COLUMN language_type TEXT",
1239
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
1240
+ ]) {
1241
+ try {
1242
+ await client.execute(col);
1243
+ } catch {
1244
+ }
1245
+ }
1162
1246
  }
1163
1247
  async function disposeDatabase() {
1248
+ if (_daemonClient) {
1249
+ _daemonClient.close();
1250
+ _daemonClient = null;
1251
+ }
1164
1252
  if (_client) {
1165
1253
  _client.close();
1166
1254
  _client = null;
1167
1255
  _resilientClient = null;
1168
1256
  }
1169
1257
  }
1170
- var _client, _resilientClient, initTurso, disposeTurso;
1258
+ var _client, _resilientClient, _daemonClient, initTurso, disposeTurso;
1171
1259
  var init_database = __esm({
1172
1260
  "src/lib/database.ts"() {
1173
1261
  "use strict";
@@ -1175,6 +1263,7 @@ var init_database = __esm({
1175
1263
  init_employees();
1176
1264
  _client = null;
1177
1265
  _resilientClient = null;
1266
+ _daemonClient = null;
1178
1267
  initTurso = initDatabase;
1179
1268
  disposeTurso = disposeDatabase;
1180
1269
  }
@@ -1610,6 +1699,7 @@ ${p.content}`).join("\n\n");
1610
1699
  import { execSync as execSync2 } from "child_process";
1611
1700
 
1612
1701
  // src/lib/store.ts
1702
+ import { createHash } from "crypto";
1613
1703
  init_database();
1614
1704
 
1615
1705
  // src/lib/keychain.ts
@@ -1645,12 +1735,20 @@ async function getMasterKey() {
1645
1735
  }
1646
1736
  const keyPath = getKeyPath();
1647
1737
  if (!existsSync3(keyPath)) {
1738
+ process.stderr.write(
1739
+ `[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
1740
+ `
1741
+ );
1648
1742
  return null;
1649
1743
  }
1650
1744
  try {
1651
1745
  const content = await readFile3(keyPath, "utf-8");
1652
1746
  return Buffer.from(content.trim(), "base64");
1653
- } catch {
1747
+ } catch (err) {
1748
+ process.stderr.write(
1749
+ `[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
1750
+ `
1751
+ );
1654
1752
  return null;
1655
1753
  }
1656
1754
  }
@@ -1815,80 +1913,85 @@ async function flushBatch() {
1815
1913
  const draft = row.draft ? 1 : 0;
1816
1914
  const memoryType = row.memory_type ?? "raw";
1817
1915
  const trajectory = row.trajectory ?? null;
1818
- return {
1819
- sql: hasVector ? `INSERT OR IGNORE INTO memories
1820
- (id, agent_id, agent_role, session_id, timestamp,
1821
- tool_name, project_name,
1822
- has_error, raw_text, vector, version, task_id, importance, status,
1823
- confidence, last_accessed,
1824
- workspace_id, document_id, user_id, char_offset, page_number,
1825
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory)
1826
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories
1827
- (id, agent_id, agent_role, session_id, timestamp,
1916
+ const contentHash = row.content_hash ?? null;
1917
+ const intent = row.intent ?? null;
1918
+ const outcome = row.outcome ?? null;
1919
+ const domain = row.domain ?? null;
1920
+ const referencedEntities = row.referenced_entities ?? null;
1921
+ const retrievalCount = row.retrieval_count ?? 0;
1922
+ const chainPosition = row.chain_position ?? null;
1923
+ const reviewStatus = row.review_status ?? null;
1924
+ const contextWindowPct = row.context_window_pct ?? null;
1925
+ const filePaths = row.file_paths ?? null;
1926
+ const commitHash = row.commit_hash ?? null;
1927
+ const durationMs = row.duration_ms ?? null;
1928
+ const tokenCost = row.token_cost ?? null;
1929
+ const audience = row.audience ?? null;
1930
+ const languageType = row.language_type ?? null;
1931
+ const parentMemoryId = row.parent_memory_id ?? null;
1932
+ const cols = `id, agent_id, agent_role, session_id, timestamp,
1828
1933
  tool_name, project_name,
1829
1934
  has_error, raw_text, vector, version, task_id, importance, status,
1830
1935
  confidence, last_accessed,
1831
1936
  workspace_id, document_id, user_id, char_offset, page_number,
1832
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory)
1833
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1834
- args: hasVector ? [
1835
- row.id,
1836
- row.agent_id,
1837
- row.agent_role,
1838
- row.session_id,
1839
- row.timestamp,
1840
- row.tool_name,
1841
- row.project_name,
1842
- row.has_error,
1843
- row.raw_text,
1844
- vectorToBlob(row.vector),
1845
- row.version,
1846
- taskId,
1847
- importance,
1848
- status,
1849
- confidence,
1850
- lastAccessed,
1851
- workspaceId,
1852
- documentId,
1853
- userId,
1854
- charOffset,
1855
- pageNumber,
1856
- sourcePath,
1857
- sourceType,
1858
- tier,
1859
- supersedesId,
1860
- draft,
1861
- memoryType,
1862
- trajectory
1863
- ] : [
1864
- row.id,
1865
- row.agent_id,
1866
- row.agent_role,
1867
- row.session_id,
1868
- row.timestamp,
1869
- row.tool_name,
1870
- row.project_name,
1871
- row.has_error,
1872
- row.raw_text,
1873
- row.version,
1874
- taskId,
1875
- importance,
1876
- status,
1877
- confidence,
1878
- lastAccessed,
1879
- workspaceId,
1880
- documentId,
1881
- userId,
1882
- charOffset,
1883
- pageNumber,
1884
- sourcePath,
1885
- sourceType,
1886
- tier,
1887
- supersedesId,
1888
- draft,
1889
- memoryType,
1890
- trajectory
1891
- ]
1937
+ source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
1938
+ intent, outcome, domain, referenced_entities, retrieval_count,
1939
+ chain_position, review_status, context_window_pct, file_paths, commit_hash,
1940
+ duration_ms, token_cost, audience, language_type, parent_memory_id`;
1941
+ const metaArgs = [
1942
+ intent,
1943
+ outcome,
1944
+ domain,
1945
+ referencedEntities,
1946
+ retrievalCount,
1947
+ chainPosition,
1948
+ reviewStatus,
1949
+ contextWindowPct,
1950
+ filePaths,
1951
+ commitHash,
1952
+ durationMs,
1953
+ tokenCost,
1954
+ audience,
1955
+ languageType,
1956
+ parentMemoryId
1957
+ ];
1958
+ const baseArgs = [
1959
+ row.id,
1960
+ row.agent_id,
1961
+ row.agent_role,
1962
+ row.session_id,
1963
+ row.timestamp,
1964
+ row.tool_name,
1965
+ row.project_name,
1966
+ row.has_error,
1967
+ row.raw_text
1968
+ ];
1969
+ const sharedArgs = [
1970
+ row.version,
1971
+ taskId,
1972
+ importance,
1973
+ status,
1974
+ confidence,
1975
+ lastAccessed,
1976
+ workspaceId,
1977
+ documentId,
1978
+ userId,
1979
+ charOffset,
1980
+ pageNumber,
1981
+ sourcePath,
1982
+ sourceType,
1983
+ tier,
1984
+ supersedesId,
1985
+ draft,
1986
+ memoryType,
1987
+ trajectory,
1988
+ contentHash
1989
+ ];
1990
+ return {
1991
+ sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
1992
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
1993
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1994
+ args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
1892
1995
  };
1893
1996
  };
1894
1997
  const globalClient = getClient();