@askexenow/exe-os 0.9.295 → 0.9.296

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 (279) hide show
  1. package/deploy/compose/cloudflared/config.yml.example +14 -9
  2. package/deploy/compose/docker-compose.yml +86 -8
  3. package/deploy/compose/sso-edge/default.conf.template +87 -0
  4. package/deploy/compose/sso-edge/entrypoint.sh +23 -0
  5. package/deploy/compose/sso-edge/sso-redirect.conf +63 -0
  6. package/deploy/stack-manifests/v0.9.json +1 -1
  7. package/dist/active-agent-AFX2FODG.js +28 -0
  8. package/dist/active-agent-E2IJA7YX.js +27 -0
  9. package/dist/agentic-ontology-A2YUZK5O.js +25 -0
  10. package/dist/assets/com.askexe.exed.plist +4 -1
  11. package/dist/backfill-metadata-OC7EOD5U.js +600 -0
  12. package/dist/behaviors-H5ZOVHDH.js +46 -0
  13. package/dist/bin/agentic-ontology-backfill.js +5 -5
  14. package/dist/bin/agentic-reflection-backfill.js +6 -6
  15. package/dist/bin/agentic-semantic-label.js +5 -5
  16. package/dist/bin/backfill-conversations.js +6 -6
  17. package/dist/bin/backfill-responses.js +6 -6
  18. package/dist/bin/backfill-vectors.js +8 -8
  19. package/dist/bin/bulk-sync-postgres.js +7 -7
  20. package/dist/bin/cc-doctor.js +4 -4
  21. package/dist/bin/cleanup-stale-review-tasks.js +11 -11
  22. package/dist/bin/cli.js +16 -16
  23. package/dist/bin/deferred-daemon-restart.js +1 -1
  24. package/dist/bin/exe-agent-config.js +2 -2
  25. package/dist/bin/exe-agent.js +4 -4
  26. package/dist/bin/exe-assign.js +8 -8
  27. package/dist/bin/exe-boot.js +21 -18
  28. package/dist/bin/exe-call.js +4 -4
  29. package/dist/bin/exe-cloud.js +7 -7
  30. package/dist/bin/exe-dispatch.js +11 -11
  31. package/dist/bin/exe-doctor.js +3 -2
  32. package/dist/bin/exe-export-behaviors.js +7 -7
  33. package/dist/bin/exe-forget.js +6 -6
  34. package/dist/bin/exe-gateway.js +7 -7
  35. package/dist/bin/exe-healthcheck.js +6 -4
  36. package/dist/bin/exe-heartbeat.js +11 -11
  37. package/dist/bin/exe-kill.js +14 -14
  38. package/dist/bin/exe-launch-agent.js +18 -18
  39. package/dist/bin/exe-new-employee.js +6 -6
  40. package/dist/bin/exe-pending-messages.js +12 -12
  41. package/dist/bin/exe-pending-notifications.js +11 -11
  42. package/dist/bin/exe-pending-reviews.js +11 -11
  43. package/dist/bin/exe-rename.js +4 -4
  44. package/dist/bin/exe-review.js +13 -13
  45. package/dist/bin/exe-search.js +5 -5
  46. package/dist/bin/exe-session-cleanup.js +16 -16
  47. package/dist/bin/exe-settings.js +39 -9
  48. package/dist/bin/exe-start-codex.js +11 -11
  49. package/dist/bin/exe-start-opencode.js +8 -8
  50. package/dist/bin/exe-status.js +12 -12
  51. package/dist/bin/exe-team.js +3 -3
  52. package/dist/bin/git-sweep.js +12 -12
  53. package/dist/bin/graph-backfill.js +4 -4
  54. package/dist/bin/graph-export.js +5 -5
  55. package/dist/bin/import-history.js +7 -7
  56. package/dist/bin/install-launchd.js +13 -6
  57. package/dist/bin/install.js +26 -14
  58. package/dist/bin/intercom-check.js +4 -4
  59. package/dist/bin/mcp-sessions.js +2 -2
  60. package/dist/bin/orchestration-metrics.js +4 -4
  61. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  62. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  63. package/dist/bin/scan-tasks.js +11 -11
  64. package/dist/bin/setup.js +1 -1
  65. package/dist/bin/shard-migrate.js +4 -4
  66. package/dist/bin/stack-update.js +2 -2
  67. package/dist/bin/vps-health-gate.js +1 -1
  68. package/dist/capability-cards-4USI7CUW.js +89 -0
  69. package/dist/capacity-monitor-WLCBTEYR.js +51 -0
  70. package/dist/catchup-brief-ZR3NX6LZ.js +175 -0
  71. package/dist/chunk-22TVSRQQ.js +226 -0
  72. package/dist/chunk-2E43UXRH.js +395 -0
  73. package/dist/chunk-2PIGT6UJ.js +460 -0
  74. package/dist/chunk-3XTMW2MZ.js +535 -0
  75. package/dist/chunk-465PQFTH.js +262 -0
  76. package/dist/chunk-5CCXU2AW.js +129 -0
  77. package/dist/chunk-5D6MPWR7.js +1094 -0
  78. package/dist/chunk-5Q4MR6SL.js +123 -0
  79. package/dist/chunk-6327RBWR.js +345 -0
  80. package/dist/chunk-6MZZREZY.js +199 -0
  81. package/dist/chunk-7DI2Q4O5.js +1186 -0
  82. package/dist/chunk-7PW5VNIY.js +122 -0
  83. package/dist/chunk-7T7Y56HW.js +43 -0
  84. package/dist/chunk-7UHCWCLT.js +128 -0
  85. package/dist/chunk-A2ZUMF6L.js +1350 -0
  86. package/dist/chunk-AKV44JEH.js +185 -0
  87. package/dist/chunk-ANHWGX5N.js +735 -0
  88. package/dist/chunk-BQ3P4TKD.js +97 -0
  89. package/dist/chunk-BUZMT3KZ.js +604 -0
  90. package/dist/chunk-C2SBESBO.js +210 -0
  91. package/dist/chunk-CLSXZUZW.js +51 -0
  92. package/dist/chunk-CONHLVAR.js +1079 -0
  93. package/dist/chunk-D3WTZPFX.js +456 -0
  94. package/dist/chunk-DE6SOIYL.js +197 -0
  95. package/dist/chunk-EIVNMA3Q.js +284 -0
  96. package/dist/chunk-EJIF4FNT.js +12 -0
  97. package/dist/chunk-FDFOW564.js +171 -0
  98. package/dist/chunk-GZUBJ5EC.js +127 -0
  99. package/dist/chunk-HGZITN22.js +105 -0
  100. package/dist/chunk-HSRKDU6X.js +362 -0
  101. package/dist/chunk-IIEN2PHV.js +85 -0
  102. package/dist/chunk-JQ56VLMM.js +567 -0
  103. package/dist/chunk-JVHHXRFY.js +280 -0
  104. package/dist/chunk-JXCXGZ3S.js +55 -0
  105. package/dist/chunk-K5ZO532Q.js +4388 -0
  106. package/dist/chunk-K6CAAMXF.js +97 -0
  107. package/dist/chunk-KA26YTNU.js +81 -0
  108. package/dist/chunk-KMUW5C3R.js +381 -0
  109. package/dist/chunk-KOO3J5PV.js +20 -0
  110. package/dist/chunk-LSV7OFIH.js +290 -0
  111. package/dist/chunk-LSVFDVNY.js +1158 -0
  112. package/dist/chunk-LXDQTW32.js +230 -0
  113. package/dist/chunk-MEP7OUVZ.js +181 -0
  114. package/dist/chunk-MN2B2LKS.js +240 -0
  115. package/dist/chunk-N2EAYPYQ.js +1352 -0
  116. package/dist/chunk-N7I2A667.js +70 -0
  117. package/dist/chunk-NLZHVIOP.js +630 -0
  118. package/dist/chunk-NUH5TRZL.js +227 -0
  119. package/dist/chunk-OAHEIH3G.js +167 -0
  120. package/dist/chunk-OBHRQGCK.js +58 -0
  121. package/dist/chunk-ODFA7B2V.js +54 -0
  122. package/dist/chunk-OSNUP45F.js +731 -0
  123. package/dist/chunk-OTPRHBTO.js +33 -0
  124. package/dist/chunk-P6MUA4QU.js +157 -0
  125. package/dist/chunk-PGIOFKSK.js +2093 -0
  126. package/dist/chunk-PSE7VHWK.js +50 -0
  127. package/dist/chunk-QIFUVZFW.js +331 -0
  128. package/dist/chunk-RDPXKTVK.js +221 -0
  129. package/dist/chunk-RKYTYJGB.js +76 -0
  130. package/dist/chunk-RXLR6EFM.js +348 -0
  131. package/dist/chunk-SDB67PQJ.js +159 -0
  132. package/dist/chunk-SF2T7MP3.js +402 -0
  133. package/dist/chunk-SLU3FRFQ.js +2133 -0
  134. package/dist/chunk-SNDZJ5IV.js +214 -0
  135. package/dist/chunk-STEEAABW.js +448 -0
  136. package/dist/chunk-TUTWNHIQ.js +244 -0
  137. package/dist/chunk-UDP35QBR.js +30 -0
  138. package/dist/chunk-UKFHNJBI.js +85 -0
  139. package/dist/chunk-VC2DTK2X.js +382 -0
  140. package/dist/chunk-VRRAE5JX.js +836 -0
  141. package/dist/chunk-VVJTBQPR.js +38 -0
  142. package/dist/chunk-W3EQ362K.js +581 -0
  143. package/dist/chunk-WHIXIFHC.js +2242 -0
  144. package/dist/chunk-WRNGJJNR.js +377 -0
  145. package/dist/chunk-WUKHLCBE.js +3313 -0
  146. package/dist/chunk-WVPLHGDG.js +150 -0
  147. package/dist/chunk-XJZBSTL5.js +204 -0
  148. package/dist/chunk-Y3PMNUM5.js +304 -0
  149. package/dist/chunk-YHVS4QOV.js +14597 -0
  150. package/dist/chunk-YJ2OYAOC.js +668 -0
  151. package/dist/chunk-YYAD2GXX.js +128 -0
  152. package/dist/chunk-ZQML7EWE.js +333 -0
  153. package/dist/co-activation-XJLH46OX.js +74 -0
  154. package/dist/co-occurrence-GNN2X526.js +95 -0
  155. package/dist/code-context-index-OCPRLFG5.js +30 -0
  156. package/dist/core-memory-J4W2IYOF.js +110 -0
  157. package/dist/crdt-sync-QCBTSHIH.js +33 -0
  158. package/dist/crm-webhook-EM442VUW.js +10 -0
  159. package/dist/cto-delegation-gate-MLJMVHBK.js +280 -0
  160. package/dist/daemon-orchestration-2VNLZVTW.js +139 -0
  161. package/dist/db-backup-VUGFTPJ4.js +43 -0
  162. package/dist/doc-graph-extractor-PNRSFPSS.js +133 -0
  163. package/dist/dreaming-SK5VEQRF.js +34 -0
  164. package/dist/entity-boost-TQWWJUC2.js +375 -0
  165. package/dist/exe-drift-N34UPO7S.js +70 -0
  166. package/dist/exe-export-KACBKGVV.js +77 -0
  167. package/dist/exe-import-GXGDWACG.js +80 -0
  168. package/dist/exe-key-XPDOZBWW.js +673 -0
  169. package/dist/exe-snapshot-32GQKGQ5.js +338 -0
  170. package/dist/fast-db-init-F3TDD5VV.js +7 -0
  171. package/dist/gateway/index.js +8 -8
  172. package/dist/git-staleness-J45WNYRF.js +112 -0
  173. package/dist/git-task-sweep-BTGVQPFB.js +42 -0
  174. package/dist/global-procedures-6JCQWU4D.js +22 -0
  175. package/dist/graph-auto-extract-3ZQNXTPC.js +183 -0
  176. package/dist/hooks/bug-report-worker.js +13 -13
  177. package/dist/hooks/codex-stop-task-finalizer.js +13 -13
  178. package/dist/hooks/commit-complete.js +13 -13
  179. package/dist/hooks/error-recall.js +6 -6
  180. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  181. package/dist/hooks/ingest-worker.js +3 -3
  182. package/dist/hooks/ingest.js +6 -6
  183. package/dist/hooks/instructions-loaded.js +4 -4
  184. package/dist/hooks/manifest.json +20 -20
  185. package/dist/hooks/notification.js +4 -4
  186. package/dist/hooks/post-compact.js +12 -12
  187. package/dist/hooks/post-tool-combined.js +6 -6
  188. package/dist/hooks/pre-compact.js +16 -16
  189. package/dist/hooks/pre-tool-use.js +16 -16
  190. package/dist/hooks/prompt-submit.js +24 -24
  191. package/dist/hooks/session-end.js +21 -21
  192. package/dist/hooks/session-start.js +12 -12
  193. package/dist/hooks/stop.js +19 -19
  194. package/dist/hooks/subagent-stop.js +12 -12
  195. package/dist/hooks/summary-worker.js +19 -19
  196. package/dist/index.js +19 -19
  197. package/dist/installer-5VPFY7SB.js +298 -0
  198. package/dist/installer-OENFPMA2.js +344 -0
  199. package/dist/installer-OIX4QOG5.js +40 -0
  200. package/dist/lib/cloud-sync.js +7 -7
  201. package/dist/lib/consolidation.js +6 -5
  202. package/dist/lib/database.js +2 -2
  203. package/dist/lib/db-daemon-client.js +2 -2
  204. package/dist/lib/db.js +2 -2
  205. package/dist/lib/embed-worker.js +1 -0
  206. package/dist/lib/embedder.js +7 -3
  207. package/dist/lib/employee-templates.js +4 -4
  208. package/dist/lib/employees.js +2 -2
  209. package/dist/lib/exe-daemon-client.js +2 -2
  210. package/dist/lib/exe-daemon.js +160 -79
  211. package/dist/lib/hybrid-search.js +5 -5
  212. package/dist/lib/identity.js +2 -2
  213. package/dist/lib/messaging.js +11 -11
  214. package/dist/lib/reminders.js +3 -3
  215. package/dist/lib/schedules.js +5 -5
  216. package/dist/lib/session-registry.js +4 -4
  217. package/dist/lib/skill-learning.js +6 -6
  218. package/dist/lib/store.js +4 -4
  219. package/dist/lib/task-router.js +3 -3
  220. package/dist/lib/tasks.js +12 -12
  221. package/dist/lib/tmux-routing.js +12 -10
  222. package/dist/lib/tmux-transport.js +1 -1
  223. package/dist/lib/token-spend.js +3 -3
  224. package/dist/lib/transport.js +2 -2
  225. package/dist/mcp/register-tools.js +62 -61
  226. package/dist/mcp/server.js +63 -62
  227. package/dist/mcp/tools/complete-reminder.js +4 -4
  228. package/dist/mcp/tools/create-reminder.js +4 -4
  229. package/dist/mcp/tools/create-task.js +14 -14
  230. package/dist/mcp/tools/deactivate-behavior.js +7 -7
  231. package/dist/mcp/tools/list-reminders.js +4 -4
  232. package/dist/mcp/tools/list-tasks.js +14 -14
  233. package/dist/mcp/tools/send-message.js +13 -13
  234. package/dist/mcp/tools/update-task.js +13 -13
  235. package/dist/mcp-http-config-PQTOLCTP.js +29 -0
  236. package/dist/memory-cards-4RVDZIY2.js +180 -0
  237. package/dist/memory-graph-extractor-L6YC7G4M.js +22 -0
  238. package/dist/memory-poisoning-defense-4YVJYH4G.js +224 -0
  239. package/dist/memory-queue-client-MVAUOZNJ.js +16 -0
  240. package/dist/memory-reflection-SHHDQNOH.js +244 -0
  241. package/dist/message-queue-client-DCKZT6X2.js +92 -0
  242. package/dist/notifications-JFR3G42W.js +47 -0
  243. package/dist/orchestration-events-MGCGPTDN.js +27 -0
  244. package/dist/orchestrator-DAFL2YZB.js +35 -0
  245. package/dist/pipeline-router-WWSZVPCH.js +15 -0
  246. package/dist/plan-limits-C7XCSDZC.js +28 -0
  247. package/dist/project-boot-N3NTBVLE.js +299 -0
  248. package/dist/projection-worker-MTPAPCWX.js +1084 -0
  249. package/dist/prospective-memory-BTIVUJSB.js +232 -0
  250. package/dist/reranker-UA6WVESJ.js +19 -0
  251. package/dist/retrieval-health-7XNZJEBF.js +12 -0
  252. package/dist/review-polling-4ALGMXC3.js +126 -0
  253. package/dist/runtime/index.js +13 -13
  254. package/dist/self-query-router-MROFQLQB.js +192 -0
  255. package/dist/session-events-CK44XOU4.js +38 -0
  256. package/dist/session-kill-telemetry-MT6ITDOG.js +31 -0
  257. package/dist/session-scope-3XDBWV65.js +88 -0
  258. package/dist/setup-wizard-X6DOD7MC.js +12 -0
  259. package/dist/skill-refinement-G2CCY3GM.js +159 -0
  260. package/dist/stack-update-JF7F56AS.js +84 -0
  261. package/dist/steward-gate-YF2CYXE7.js +15 -0
  262. package/dist/task-enforcement-YN6HK7NE.js +506 -0
  263. package/dist/task-scope-CVK6ISCZ.js +37 -0
  264. package/dist/tasks-crud-NTNET4JE.js +79 -0
  265. package/dist/tasks-notify-4LJVFPCV.js +40 -0
  266. package/dist/tasks-review-3V4WOIRG.js +49 -0
  267. package/dist/telemetry-upload-5PNUKGTM.js +741 -0
  268. package/dist/token-budget-E46G7ZAQ.js +86 -0
  269. package/dist/tool-capability-index-JDSMKJER.js +10 -0
  270. package/dist/tool-telemetry-J3NLS3LJ.js +17 -0
  271. package/dist/tui/App.js +18 -18
  272. package/dist/tui-data-6DOMUUCM.js +260 -0
  273. package/dist/wiki-acl-5UK37LKF.js +111 -0
  274. package/dist/worker-gate-FM7AEC7G.js +21 -0
  275. package/dist/workflow-engine-2EDUHUIY.js +28 -0
  276. package/dist/worktree-7YKKJIYR.js +28 -0
  277. package/dist/worktree-sweep-C3ELFGDN.js +21 -0
  278. package/package.json +1 -1
  279. package/release-notes.json +23 -23
@@ -0,0 +1,836 @@
1
+ import {
2
+ extractKeywords,
3
+ keywordsToString
4
+ } from "./chunk-CHCA3ZM2.js";
5
+ import {
6
+ blobToVector
7
+ } from "./chunk-OTVEIJUQ.js";
8
+ import {
9
+ findScopedDuplicate,
10
+ governMemoryRecord,
11
+ schedulePostWriteMemoryHygiene
12
+ } from "./chunk-C2SBESBO.js";
13
+ import {
14
+ orgBus
15
+ } from "./chunk-MP2AFCGL.js";
16
+ import {
17
+ disposeTurso,
18
+ ensureSchema,
19
+ getClient,
20
+ initTurso
21
+ } from "./chunk-WUKHLCBE.js";
22
+ import {
23
+ EMBEDDING_DIM
24
+ } from "./chunk-FXU7JOXK.js";
25
+ import {
26
+ getMasterKey
27
+ } from "./chunk-Z42MXYWW.js";
28
+ import {
29
+ loadConfig
30
+ } from "./chunk-R36FAN53.js";
31
+
32
+ // src/lib/store.ts
33
+ var _debugStore = process.env.EXE_DEBUG === "1";
34
+ function logStoreDebug(context, err) {
35
+ if (_debugStore) {
36
+ process.stderr.write(
37
+ `[store] ${context}: ${err instanceof Error ? err.message : String(err)}
38
+ `
39
+ );
40
+ }
41
+ }
42
+ function logStoreWarn(context, err) {
43
+ process.stderr.write(
44
+ `[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
45
+ `
46
+ );
47
+ }
48
+ var SHARD_CB_MAX_FAILURES = 3;
49
+ var SHARD_CB_COOLDOWN_MS = 5 * 6e4;
50
+ var _shardCircuits = /* @__PURE__ */ new Map();
51
+ function isShardCircuitOpen(project) {
52
+ const state = _shardCircuits.get(project);
53
+ if (!state || state.openedAt === null) return false;
54
+ if (Date.now() - state.openedAt > SHARD_CB_COOLDOWN_MS) {
55
+ state.openedAt = null;
56
+ state.failures = 0;
57
+ return false;
58
+ }
59
+ return true;
60
+ }
61
+ function recordShardFailure(project, error) {
62
+ const state = _shardCircuits.get(project) ?? { failures: 0, openedAt: null, lastError: "" };
63
+ state.failures++;
64
+ state.lastError = error;
65
+ if (state.failures >= SHARD_CB_MAX_FAILURES && state.openedAt === null) {
66
+ state.openedAt = Date.now();
67
+ process.stderr.write(
68
+ `[store] Shard circuit OPEN for "${project}" after ${state.failures} consecutive failures. Will retry in ${SHARD_CB_COOLDOWN_MS / 6e4}min. Last error: ${error}
69
+ `
70
+ );
71
+ void import("./orchestration-events-MGCGPTDN.js").then(({ recordOrchestrationEventBestEffort }) => {
72
+ recordOrchestrationEventBestEffort({
73
+ eventType: "shard.circuit_open",
74
+ source: "store.recordShardFailure",
75
+ severity: "error",
76
+ projectName: project,
77
+ payload: { failures: state.failures, lastError: error.slice(0, 200) }
78
+ });
79
+ }).catch(() => {
80
+ });
81
+ }
82
+ _shardCircuits.set(project, state);
83
+ }
84
+ function recordShardSuccess(project) {
85
+ _shardCircuits.delete(project);
86
+ }
87
+ var INIT_MAX_RETRIES = 3;
88
+ var INIT_RETRY_DELAY_MS = 1e3;
89
+ function isBusyError(err) {
90
+ if (err instanceof Error) {
91
+ const msg = err.message.toLowerCase();
92
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
93
+ }
94
+ return false;
95
+ }
96
+ async function retryOnBusy(fn, label) {
97
+ for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
98
+ try {
99
+ return await fn();
100
+ } catch (err) {
101
+ if (!isBusyError(err) || attempt === INIT_MAX_RETRIES) throw err;
102
+ process.stderr.write(
103
+ `[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
104
+ `
105
+ );
106
+ await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
107
+ }
108
+ }
109
+ throw new Error("unreachable");
110
+ }
111
+ var _pendingRecords = [];
112
+ var _batchSize = 20;
113
+ var _flushIntervalMs = 1e4;
114
+ var _flushTimer = null;
115
+ var _flushing = false;
116
+ var _nextVersion = 1;
117
+ async function initStore(options) {
118
+ if (_flushTimer !== null) {
119
+ clearInterval(_flushTimer);
120
+ _flushTimer = null;
121
+ }
122
+ _pendingRecords = [];
123
+ _flushing = false;
124
+ _batchSize = options?.batchSize ?? 20;
125
+ _flushIntervalMs = options?.flushIntervalMs ?? 1e4;
126
+ let dbPath = options?.dbPath;
127
+ if (!dbPath) {
128
+ const config = await loadConfig();
129
+ dbPath = config.dbPath;
130
+ }
131
+ let masterKey = options?.masterKey ?? null;
132
+ if (!masterKey) {
133
+ masterKey = await getMasterKey();
134
+ if (!masterKey) {
135
+ throw new Error(
136
+ "No encryption key found. Run /exe-setup to generate one."
137
+ );
138
+ }
139
+ }
140
+ const hexKey = masterKey.toString("hex");
141
+ await initTurso({
142
+ dbPath,
143
+ encryptionKey: hexKey
144
+ });
145
+ await retryOnBusy(() => ensureSchema(), "ensureSchema");
146
+ try {
147
+ const { initDaemonClient } = await import("./lib/database.js");
148
+ await initDaemonClient();
149
+ } catch (e) {
150
+ logStoreWarn("catch", e);
151
+ }
152
+ if (!options?.lightweight) {
153
+ try {
154
+ if (process.env.EXE_DISABLE_SHARDING !== "1") {
155
+ const { initShardManager } = await import("./shard-manager-P5ZJH4AX.js");
156
+ initShardManager(hexKey);
157
+ }
158
+ } catch (e) {
159
+ logStoreWarn("catch", e);
160
+ }
161
+ const client = getClient();
162
+ const vResult = await retryOnBusy(
163
+ () => client.execute("SELECT MAX(version) as max_v FROM memories"),
164
+ "version-query"
165
+ );
166
+ _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
167
+ try {
168
+ const { loadGlobalProcedures } = await import("./global-procedures-6JCQWU4D.js");
169
+ await loadGlobalProcedures();
170
+ } catch (e) {
171
+ logStoreWarn("catch", e);
172
+ }
173
+ }
174
+ }
175
+ function classifyTier(record) {
176
+ if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
177
+ if (["store_memory", "manual"].includes(record.tool_name ?? "") && (record.importance ?? 0) >= 5) return 2;
178
+ return 3;
179
+ }
180
+ function inferFilePaths(record) {
181
+ if (!["Read", "Write", "Edit"].includes(record.tool_name)) return null;
182
+ const firstLine = record.raw_text.split("\n")[0] ?? "";
183
+ const match = firstLine.match(/(\/[\w./-]+\.\w+)/);
184
+ return match ? JSON.stringify([match[1]]) : null;
185
+ }
186
+ function inferCommitHash(record) {
187
+ if (record.tool_name !== "Bash") return null;
188
+ const match = record.raw_text.match(/\b([a-f0-9]{7,40})\b/);
189
+ return match ? match[1] : null;
190
+ }
191
+ function inferLanguageType(record) {
192
+ const text = record.raw_text;
193
+ if (!text || text.length < 10) return null;
194
+ const trimmed = text.trimStart();
195
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) return "json";
196
+ if (/\b(SELECT|INSERT|UPDATE|DELETE|CREATE TABLE|ALTER TABLE)\b/i.test(text)) return "sql";
197
+ if (/\b(function |const |import |export |class |def |async |=>)\b/.test(text)) return "code";
198
+ if (trimmed.startsWith("#") || trimmed.startsWith("*")) return "prose";
199
+ return "mixed";
200
+ }
201
+ function inferDomain(record) {
202
+ const proj = (record.project_name ?? "").toLowerCase();
203
+ if (proj.includes("marketing") || proj.includes("content")) return "marketing";
204
+ if (proj.includes("crm") || proj.includes("customer")) return "customer";
205
+ return null;
206
+ }
207
+ async function writeMemory(record) {
208
+ if (record.agent_id) record.agent_id = record.agent_id.toLowerCase();
209
+ if (record.vector !== null && record.vector.length !== EMBEDDING_DIM) {
210
+ throw new Error(
211
+ `Expected ${EMBEDDING_DIM}-dim vector, got ${record.vector.length}`
212
+ );
213
+ }
214
+ const governed = governMemoryRecord(record);
215
+ if (governed.shouldDrop) return;
216
+ record = governed.record;
217
+ const contentHash = governed.contentHash;
218
+ const memoryType = record.memory_type ?? "raw";
219
+ if (_pendingRecords.some(
220
+ (r) => r.content_hash === contentHash && r.agent_id === record.agent_id && r.project_name === record.project_name && (r.memory_type ?? "raw") === memoryType
221
+ )) {
222
+ return;
223
+ }
224
+ try {
225
+ const existing = await findScopedDuplicate({
226
+ contentHash,
227
+ agentId: record.agent_id,
228
+ projectName: record.project_name,
229
+ memoryType
230
+ });
231
+ if (existing) return;
232
+ } catch (e) {
233
+ logStoreWarn("catch", e);
234
+ }
235
+ if (!record.session_scope) {
236
+ try {
237
+ const { resolveExeSession } = await import("./lib/tmux-routing.js");
238
+ record.session_scope = resolveExeSession() ?? null;
239
+ } catch {
240
+ }
241
+ }
242
+ const dbRow = {
243
+ id: record.id,
244
+ agent_id: record.agent_id,
245
+ agent_role: record.agent_role,
246
+ session_id: record.session_id,
247
+ timestamp: record.timestamp,
248
+ tool_name: record.tool_name,
249
+ project_name: record.project_name,
250
+ has_error: record.has_error ? 1 : 0,
251
+ raw_text: record.raw_text,
252
+ vector: record.vector,
253
+ version: 0,
254
+ // Placeholder — assigned atomically at flush time
255
+ task_id: record.task_id ?? null,
256
+ importance: record.importance ?? 5,
257
+ status: record.status ?? "active",
258
+ confidence: record.confidence ?? 0.7,
259
+ last_accessed: record.last_accessed ?? record.timestamp,
260
+ workspace_id: record.workspace_id ?? null,
261
+ document_id: record.document_id ?? null,
262
+ user_id: record.user_id ?? null,
263
+ char_offset: record.char_offset ?? null,
264
+ page_number: record.page_number ?? null,
265
+ source_path: record.source_path ?? null,
266
+ source_type: record.source_type ?? null,
267
+ tier: record.tier ?? classifyTier(record),
268
+ supersedes_id: record.supersedes_id ?? null,
269
+ valid_from: record.valid_from ?? record.timestamp,
270
+ invalid_at: record.invalid_at ?? null,
271
+ draft: record.draft ? 1 : 0,
272
+ memory_type: memoryType,
273
+ trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
274
+ content_hash: contentHash,
275
+ intent: record.intent ?? null,
276
+ outcome: record.outcome ?? null,
277
+ domain: record.domain ?? inferDomain(record),
278
+ referenced_entities: record.referenced_entities ?? null,
279
+ retrieval_count: record.retrieval_count ?? 0,
280
+ chain_position: record.chain_position ?? null,
281
+ review_status: record.review_status ?? null,
282
+ context_window_pct: record.context_window_pct ?? null,
283
+ file_paths: record.file_paths ?? inferFilePaths(record),
284
+ commit_hash: record.commit_hash ?? inferCommitHash(record),
285
+ duration_ms: record.duration_ms ?? null,
286
+ token_cost: record.token_cost ?? null,
287
+ audience: record.audience ?? null,
288
+ language_type: record.language_type ?? inferLanguageType(record),
289
+ parent_memory_id: record.parent_memory_id ?? null,
290
+ procedure_for: record.procedure_for ?? null,
291
+ session_scope: record.session_scope ?? null,
292
+ keywords: record.keywords ?? keywordsToString(extractKeywords(record.raw_text)),
293
+ founder_id: record.founder_id ?? null
294
+ };
295
+ try {
296
+ const { checkMemoryPoisoning } = await import("./memory-poisoning-defense-4YVJYH4G.js");
297
+ const poisonResult = await checkMemoryPoisoning({
298
+ memoryId: dbRow.id,
299
+ vector: Array.isArray(dbRow.vector) ? dbRow.vector : void 0,
300
+ agentId: dbRow.agent_id,
301
+ projectName: dbRow.project_name,
302
+ toolName: dbRow.tool_name,
303
+ sessionId: dbRow.session_id,
304
+ importance: dbRow.importance ?? 5
305
+ });
306
+ if (poisonResult.quarantined) {
307
+ dbRow.quarantined = 1;
308
+ dbRow.quarantine_reason = poisonResult.reason ?? "flagged";
309
+ }
310
+ } catch {
311
+ }
312
+ _pendingRecords.push(dbRow);
313
+ orgBus.emit({
314
+ type: "memory_stored",
315
+ agentId: record.agent_id,
316
+ project: record.project_name,
317
+ timestamp: record.timestamp
318
+ });
319
+ const MAX_PENDING = 1e3;
320
+ if (_pendingRecords.length >= MAX_PENDING) {
321
+ _pendingRecords.shift();
322
+ process.stderr.write(`[exe-os] \u26A0 Memory buffer full (${MAX_PENDING}) \u2014 oldest record dropped. This indicates sustained high write volume.
323
+ `);
324
+ }
325
+ if (_flushTimer === null) {
326
+ _flushTimer = setInterval(() => {
327
+ void flushBatch();
328
+ }, _flushIntervalMs);
329
+ if (_flushTimer && typeof _flushTimer === "object" && "unref" in _flushTimer) {
330
+ _flushTimer.unref();
331
+ }
332
+ }
333
+ if (_pendingRecords.length >= _batchSize) {
334
+ await flushBatch();
335
+ }
336
+ }
337
+ async function flushBatch() {
338
+ if (_flushing || _pendingRecords.length === 0) return 0;
339
+ _flushing = true;
340
+ try {
341
+ const batch = _pendingRecords.slice(0);
342
+ const client = getClient();
343
+ const interactiveTx = client.interactiveTransactions !== false;
344
+ if (interactiveTx) await client.execute("BEGIN IMMEDIATE");
345
+ const vResult = await client.execute("SELECT COALESCE(MAX(version), 0) as max_v FROM memories");
346
+ let baseVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
347
+ for (const row of batch) {
348
+ row.version = baseVersion++;
349
+ }
350
+ let _extractKeywords = null;
351
+ let _keywordsToString = null;
352
+ try {
353
+ const mod = await import("./keyword-extractor-UJHFWVZE.js");
354
+ _extractKeywords = mod.extractKeywords;
355
+ _keywordsToString = mod.keywordsToString;
356
+ } catch {
357
+ }
358
+ const buildStmt = (row) => {
359
+ const hasVector = row.vector !== null;
360
+ const taskId = row.task_id ?? null;
361
+ const importance = row.importance ?? 5;
362
+ const status = row.status ?? "active";
363
+ const confidence = row.confidence ?? 0.7;
364
+ const lastAccessed = row.last_accessed ?? row.timestamp;
365
+ const workspaceId = row.workspace_id ?? null;
366
+ const documentId = row.document_id ?? null;
367
+ const userId = row.user_id ?? null;
368
+ const charOffset = row.char_offset ?? null;
369
+ const pageNumber = row.page_number ?? null;
370
+ const sourcePath = row.source_path ?? null;
371
+ const sourceType = row.source_type ?? null;
372
+ const tier = row.tier ?? 3;
373
+ const supersedesId = row.supersedes_id ?? null;
374
+ const validFrom = row.valid_from ?? row.timestamp;
375
+ const invalidAt = row.invalid_at ?? null;
376
+ const draft = row.draft ? 1 : 0;
377
+ const memoryType = row.memory_type ?? "raw";
378
+ const trajectory = row.trajectory ?? null;
379
+ const contentHash = row.content_hash ?? null;
380
+ const keywords = row.keywords ?? (_extractKeywords && _keywordsToString ? _keywordsToString(_extractKeywords(row.raw_text)) : "");
381
+ const intent = row.intent ?? null;
382
+ const outcome = row.outcome ?? null;
383
+ const domain = row.domain ?? null;
384
+ const referencedEntities = row.referenced_entities ?? null;
385
+ const retrievalCount = row.retrieval_count ?? 0;
386
+ const chainPosition = row.chain_position ?? null;
387
+ const reviewStatus = row.review_status ?? null;
388
+ const contextWindowPct = row.context_window_pct ?? null;
389
+ const filePaths = row.file_paths ?? null;
390
+ const commitHash = row.commit_hash ?? null;
391
+ const durationMs = row.duration_ms ?? null;
392
+ const tokenCost = row.token_cost ?? null;
393
+ const audience = row.audience ?? null;
394
+ const languageType = row.language_type ?? null;
395
+ const parentMemoryId = row.parent_memory_id ?? null;
396
+ const procedureFor = row.procedure_for ?? null;
397
+ const sessionScope = row.session_scope ?? null;
398
+ const founderId = row.founder_id ?? null;
399
+ const cols = `id, agent_id, agent_role, session_id, timestamp,
400
+ tool_name, project_name,
401
+ has_error, raw_text, vector, version, task_id, importance, status,
402
+ confidence, last_accessed,
403
+ workspace_id, document_id, user_id, char_offset, page_number,
404
+ source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
405
+ intent, outcome, domain, referenced_entities, retrieval_count,
406
+ chain_position, review_status, context_window_pct, file_paths, commit_hash,
407
+ duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for, session_scope, keywords, founder_id`;
408
+ const metaArgs = [
409
+ intent,
410
+ outcome,
411
+ domain,
412
+ referencedEntities,
413
+ retrievalCount,
414
+ chainPosition,
415
+ reviewStatus,
416
+ contextWindowPct,
417
+ filePaths,
418
+ commitHash,
419
+ durationMs,
420
+ tokenCost,
421
+ audience,
422
+ languageType,
423
+ parentMemoryId,
424
+ procedureFor,
425
+ sessionScope,
426
+ keywords,
427
+ founderId
428
+ ];
429
+ const baseArgs = [
430
+ row.id,
431
+ row.agent_id,
432
+ row.agent_role,
433
+ row.session_id,
434
+ row.timestamp,
435
+ row.tool_name,
436
+ row.project_name,
437
+ row.has_error,
438
+ row.raw_text
439
+ ];
440
+ const sharedArgs = [
441
+ row.version,
442
+ taskId,
443
+ importance,
444
+ status,
445
+ confidence,
446
+ lastAccessed,
447
+ workspaceId,
448
+ documentId,
449
+ userId,
450
+ charOffset,
451
+ pageNumber,
452
+ sourcePath,
453
+ sourceType,
454
+ tier,
455
+ supersedesId,
456
+ validFrom,
457
+ invalidAt,
458
+ draft,
459
+ memoryType,
460
+ trajectory,
461
+ contentHash
462
+ ];
463
+ return {
464
+ sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
465
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
466
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
467
+ args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
468
+ };
469
+ };
470
+ const globalStmts = batch.map(buildStmt);
471
+ if (interactiveTx) {
472
+ try {
473
+ for (const stmt of globalStmts) {
474
+ await client.execute(stmt);
475
+ }
476
+ await client.execute("COMMIT");
477
+ } catch (txErr) {
478
+ try {
479
+ await client.execute("ROLLBACK");
480
+ } catch {
481
+ }
482
+ throw txErr;
483
+ }
484
+ } else {
485
+ await client.batch(globalStmts, "write");
486
+ }
487
+ _nextVersion = baseVersion;
488
+ try {
489
+ const { insertMemoryCardsForBatch } = await import("./memory-cards-4RVDZIY2.js");
490
+ await insertMemoryCardsForBatch(batch);
491
+ } catch (e) {
492
+ logStoreWarn("catch", e);
493
+ }
494
+ try {
495
+ const { insertOntologyForBatch } = await import("./agentic-ontology-A2YUZK5O.js");
496
+ await insertOntologyForBatch(batch);
497
+ } catch (e) {
498
+ logStoreWarn("catch", e);
499
+ }
500
+ try {
501
+ const { extractGraphForBatch } = await import("./memory-graph-extractor-L6YC7G4M.js");
502
+ await extractGraphForBatch(batch);
503
+ } catch (e) {
504
+ logStoreWarn("catch", e);
505
+ }
506
+ schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
507
+ _pendingRecords.splice(0, batch.length);
508
+ try {
509
+ const { isShardingEnabled, getReadyShardClient } = await import("./shard-manager-P5ZJH4AX.js");
510
+ if (process.env.EXE_DISABLE_SHARDING !== "1" && isShardingEnabled()) {
511
+ const byProject = /* @__PURE__ */ new Map();
512
+ let skippedUnknown = 0;
513
+ for (const row of batch) {
514
+ const proj = row.project_name?.trim();
515
+ if (!proj) {
516
+ skippedUnknown++;
517
+ continue;
518
+ }
519
+ if (!byProject.has(proj)) byProject.set(proj, []);
520
+ byProject.get(proj).push(row);
521
+ }
522
+ if (skippedUnknown > 0) {
523
+ process.stderr.write(
524
+ `[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
525
+ `
526
+ );
527
+ }
528
+ for (const [project, rows] of byProject) {
529
+ if (isShardCircuitOpen(project)) {
530
+ logStoreDebug("shard-circuit", `Skipping shard write for "${project}" \u2014 circuit open`);
531
+ continue;
532
+ }
533
+ try {
534
+ const shardClient = await getReadyShardClient(project);
535
+ const shardStmts = rows.map(buildStmt);
536
+ await shardClient.batch(shardStmts, "write");
537
+ recordShardSuccess(project);
538
+ } catch (err) {
539
+ const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
540
+ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
541
+ recordShardFailure(project, fullError);
542
+ process.stderr.write(
543
+ `[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
544
+ `
545
+ );
546
+ }
547
+ }
548
+ }
549
+ } catch (e) {
550
+ logStoreWarn("catch", e);
551
+ }
552
+ return batch.length;
553
+ } finally {
554
+ _flushing = false;
555
+ }
556
+ }
557
+ function buildWikiScopeFilter(options, columnPrefix) {
558
+ const args = [];
559
+ let clause = "";
560
+ if (options?.workspaceId !== void 0) {
561
+ clause += ` AND ${columnPrefix}workspace_id = ?`;
562
+ args.push(options.workspaceId);
563
+ }
564
+ if (options?.userId === void 0) {
565
+ clause += ` AND ${columnPrefix}user_id IS NULL`;
566
+ } else if (options.userId === null) {
567
+ clause += ` AND ${columnPrefix}user_id IS NULL`;
568
+ } else {
569
+ clause += ` AND (${columnPrefix}user_id = ? OR ${columnPrefix}user_id IS NULL)`;
570
+ args.push(options.userId);
571
+ }
572
+ return { clause, args };
573
+ }
574
+ function buildRawVisibilityFilter(options, columnPrefix) {
575
+ if (options?.includeRaw === false) {
576
+ return {
577
+ clause: ` AND COALESCE(${columnPrefix}memory_type, 'raw') != 'raw'`,
578
+ args: []
579
+ };
580
+ }
581
+ return { clause: "", args: [] };
582
+ }
583
+ async function searchMemories(queryVector, agentId, options) {
584
+ let client;
585
+ try {
586
+ const { isShardingEnabled, shardExists, getReadyShardClient } = await import("./shard-manager-P5ZJH4AX.js");
587
+ if (isShardingEnabled() && options?.projectName && shardExists(options.projectName)) {
588
+ client = await getReadyShardClient(options.projectName);
589
+ } else {
590
+ client = getClient();
591
+ }
592
+ } catch (e) {
593
+ logStoreDebug("shard routing fallback", e);
594
+ client = getClient();
595
+ }
596
+ const limit = options?.limit ?? 10;
597
+ const activeEmbeddingModel = (await loadConfig()).modelFile;
598
+ let hasEmbeddingModelCol = false;
599
+ try {
600
+ const info = await client.execute("PRAGMA table_info(memories)");
601
+ hasEmbeddingModelCol = info.rows.some((r) => r.name === "embedding_model");
602
+ } catch (e) {
603
+ logStoreDebug("embedding_model column check failed", e);
604
+ }
605
+ const statusFilter = options?.includeArchived ? "" : `
606
+ AND COALESCE(status, 'active') = 'active'`;
607
+ const draftFilter = options?.includeDrafts ? "" : `
608
+ AND (draft = 0 OR draft IS NULL)`;
609
+ let sql = `SELECT id, agent_id, agent_role, session_id, timestamp,
610
+ tool_name, project_name,
611
+ has_error, raw_text, vector, importance, status,
612
+ confidence, last_accessed,
613
+ workspace_id, document_id, user_id,
614
+ char_offset, page_number,
615
+ source_path, source_type, strength
616
+ FROM memories
617
+ WHERE (agent_id = ? OR agent_id = 'wiki')
618
+ AND vector IS NOT NULL${statusFilter}${draftFilter}
619
+ AND COALESCE(confidence, 0.7) >= 0.3`;
620
+ const args = [agentId];
621
+ if (hasEmbeddingModelCol && typeof activeEmbeddingModel === "string" && activeEmbeddingModel.length > 0) {
622
+ sql += `
623
+ AND (embedding_model = ? OR embedding_model IS NULL)`;
624
+ args.push(activeEmbeddingModel);
625
+ }
626
+ try {
627
+ const { founderScopeFilter } = await import("./founder-context-QAAWZEZM.js");
628
+ const founderFilter = founderScopeFilter(options?.founderId);
629
+ sql += founderFilter.sql;
630
+ args.push(...founderFilter.args.filter((a) => a !== null));
631
+ } catch {
632
+ }
633
+ if (options?.asOf) {
634
+ sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
635
+ args.push(options.asOf, options.asOf);
636
+ } else {
637
+ sql += ` AND invalid_at IS NULL`;
638
+ }
639
+ const scope = buildWikiScopeFilter(options, "");
640
+ sql += scope.clause;
641
+ args.push(...scope.args);
642
+ const rawVisibility = buildRawVisibilityFilter(options, "");
643
+ sql += rawVisibility.clause;
644
+ args.push(...rawVisibility.args);
645
+ if (options?.projectName) {
646
+ sql += ` AND project_name = ?`;
647
+ args.push(options.projectName);
648
+ }
649
+ if (options?.sessionScope) {
650
+ sql += ` AND (session_scope = ? OR session_scope IS NULL)`;
651
+ args.push(options.sessionScope);
652
+ }
653
+ if (options?.toolName) {
654
+ sql += ` AND tool_name = ?`;
655
+ args.push(options.toolName);
656
+ }
657
+ if (options?.hasError !== void 0) {
658
+ sql += ` AND has_error = ?`;
659
+ args.push(options.hasError ? 1 : 0);
660
+ }
661
+ if (options?.since) {
662
+ sql += ` AND timestamp >= ?`;
663
+ args.push(options.since);
664
+ }
665
+ if (options?.memoryTypes && options.memoryTypes.length > 0) {
666
+ const uniqueTypes = [...new Set(options.memoryTypes)];
667
+ sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
668
+ args.push(...uniqueTypes);
669
+ } else if (options?.memoryType) {
670
+ sql += ` AND memory_type = ?`;
671
+ args.push(options.memoryType);
672
+ }
673
+ sql += ` ORDER BY vector_distance_cos(vector, vector32(?))`;
674
+ args.push(vectorToBlob(queryVector));
675
+ sql += ` LIMIT ?`;
676
+ args.push(limit);
677
+ const result = await client.execute({ sql, args });
678
+ return result.rows.map((row) => ({
679
+ id: row.id,
680
+ agent_id: row.agent_id,
681
+ agent_role: row.agent_role,
682
+ session_id: row.session_id,
683
+ timestamp: row.timestamp,
684
+ tool_name: row.tool_name,
685
+ project_name: row.project_name,
686
+ has_error: row.has_error === 1,
687
+ raw_text: row.raw_text,
688
+ vector: row.vector == null ? [] : Array.isArray(row.vector) ? row.vector : blobToVector(row.vector),
689
+ importance: row.importance ?? 5,
690
+ status: row.status ?? "active",
691
+ confidence: row.confidence ?? 0.7,
692
+ last_accessed: row.last_accessed ?? row.timestamp,
693
+ workspace_id: row.workspace_id ?? null,
694
+ document_id: row.document_id ?? null,
695
+ user_id: row.user_id ?? null,
696
+ char_offset: row.char_offset ?? null,
697
+ page_number: row.page_number ?? null,
698
+ source_path: row.source_path ?? null,
699
+ source_type: row.source_type ?? null,
700
+ strength: row.strength ?? 1
701
+ }));
702
+ }
703
+ async function attachDocumentMetadata(records) {
704
+ const docIds = [
705
+ ...new Set(
706
+ records.map((r) => r.document_id).filter((id) => typeof id === "string" && id.length > 0)
707
+ )
708
+ ];
709
+ if (docIds.length === 0) return records;
710
+ try {
711
+ const client = getClient();
712
+ const placeholders = docIds.map(() => "?").join(",");
713
+ const result = await client.execute({
714
+ sql: `SELECT id, filename, mime, source_type, uploaded_at
715
+ FROM documents
716
+ WHERE id IN (${placeholders})`,
717
+ args: docIds
718
+ });
719
+ const byId = /* @__PURE__ */ new Map();
720
+ for (const row of result.rows) {
721
+ const id = row.id;
722
+ byId.set(id, {
723
+ document_id: id,
724
+ filename: row.filename,
725
+ mime: row.mime ?? null,
726
+ source_type: row.source_type ?? null,
727
+ uploaded_at: row.uploaded_at
728
+ });
729
+ }
730
+ for (const record of records) {
731
+ if (!record.document_id) continue;
732
+ record.document_metadata = byId.get(record.document_id) ?? null;
733
+ }
734
+ } catch (e) {
735
+ logStoreWarn("catch", e);
736
+ }
737
+ return records;
738
+ }
739
+ async function flushTier3(agentId, options) {
740
+ const client = getClient();
741
+ const maxAge = options?.maxAgeHours ?? 72;
742
+ const cutoff = new Date(Date.now() - maxAge * 36e5).toISOString();
743
+ if (options?.dryRun) {
744
+ const result2 = await client.execute({
745
+ sql: `SELECT COUNT(*) as cnt FROM memories
746
+ WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
747
+ args: [agentId, cutoff]
748
+ });
749
+ return { archived: Number(result2.rows[0]?.cnt ?? 0) };
750
+ }
751
+ const result = await client.execute({
752
+ sql: `UPDATE memories SET status = 'archived'
753
+ WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
754
+ args: [agentId, cutoff]
755
+ });
756
+ return { archived: result.rowsAffected };
757
+ }
758
+ async function disposeStore() {
759
+ if (_flushTimer !== null) {
760
+ clearInterval(_flushTimer);
761
+ _flushTimer = null;
762
+ }
763
+ if (_pendingRecords.length > 0) {
764
+ await flushBatch();
765
+ }
766
+ await disposeTurso();
767
+ _pendingRecords = [];
768
+ _nextVersion = 1;
769
+ }
770
+ function vectorToSqlLiteral(vector) {
771
+ const f32 = vector instanceof Float32Array ? vector : new Float32Array(vector);
772
+ return JSON.stringify(Array.from(f32));
773
+ }
774
+ var vectorToBlob = vectorToSqlLiteral;
775
+ async function updateMemoryStatus(id, status) {
776
+ const client = getClient();
777
+ await client.execute({
778
+ sql: `UPDATE memories SET status = ? WHERE id = ?`,
779
+ args: [status, id]
780
+ });
781
+ }
782
+ async function reserveVersions(count) {
783
+ const client = getClient();
784
+ await client.execute("BEGIN IMMEDIATE");
785
+ try {
786
+ const vResult = await client.execute("SELECT COALESCE(MAX(version), 0) as max_v FROM memories");
787
+ let baseVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
788
+ if (_nextVersion > baseVersion) {
789
+ baseVersion = _nextVersion;
790
+ }
791
+ const reserved = [];
792
+ for (let i = 0; i < count; i++) {
793
+ reserved.push(baseVersion + i);
794
+ }
795
+ _nextVersion = baseVersion + count;
796
+ await client.execute("COMMIT");
797
+ return reserved;
798
+ } catch (err) {
799
+ try {
800
+ await client.execute("ROLLBACK");
801
+ } catch {
802
+ }
803
+ throw err;
804
+ }
805
+ }
806
+ async function getMemoryCardinality(agentId) {
807
+ try {
808
+ const client = getClient();
809
+ const result = await client.execute({
810
+ sql: `SELECT COUNT(*) as cnt FROM memories WHERE agent_id = ? AND COALESCE(status, 'active') = 'active'`,
811
+ args: [agentId]
812
+ });
813
+ return Number(result.rows[0]?.cnt) || 0;
814
+ } catch (e) {
815
+ logStoreWarn("getMemoryCardinality", e);
816
+ return 0;
817
+ }
818
+ }
819
+
820
+ export {
821
+ initStore,
822
+ classifyTier,
823
+ writeMemory,
824
+ flushBatch,
825
+ buildWikiScopeFilter,
826
+ buildRawVisibilityFilter,
827
+ searchMemories,
828
+ attachDocumentMetadata,
829
+ flushTier3,
830
+ disposeStore,
831
+ vectorToSqlLiteral,
832
+ vectorToBlob,
833
+ updateMemoryStatus,
834
+ reserveVersions,
835
+ getMemoryCardinality
836
+ };