@marifold/core 0.60.0

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 (310) hide show
  1. package/LICENSE +674 -0
  2. package/dist/agent/AgentEvents.d.ts +106 -0
  3. package/dist/agent/AgentEvents.d.ts.map +1 -0
  4. package/dist/agent/AgentEvents.js +3 -0
  5. package/dist/agent/AgentEvents.js.map +1 -0
  6. package/dist/agent/AgentHistory.d.ts +27 -0
  7. package/dist/agent/AgentHistory.d.ts.map +1 -0
  8. package/dist/agent/AgentHistory.js +42 -0
  9. package/dist/agent/AgentHistory.js.map +1 -0
  10. package/dist/agent/AgentRunner.d.ts +149 -0
  11. package/dist/agent/AgentRunner.d.ts.map +1 -0
  12. package/dist/agent/AgentRunner.js +727 -0
  13. package/dist/agent/AgentRunner.js.map +1 -0
  14. package/dist/agent/ApprovalPolicy.d.ts +71 -0
  15. package/dist/agent/ApprovalPolicy.d.ts.map +1 -0
  16. package/dist/agent/ApprovalPolicy.js +29 -0
  17. package/dist/agent/ApprovalPolicy.js.map +1 -0
  18. package/dist/agent/ControlBlockTools.d.ts +9 -0
  19. package/dist/agent/ControlBlockTools.d.ts.map +1 -0
  20. package/dist/agent/ControlBlockTools.js +49 -0
  21. package/dist/agent/ControlBlockTools.js.map +1 -0
  22. package/dist/agent/RunWorkspace.d.ts +92 -0
  23. package/dist/agent/RunWorkspace.d.ts.map +1 -0
  24. package/dist/agent/RunWorkspace.js +328 -0
  25. package/dist/agent/RunWorkspace.js.map +1 -0
  26. package/dist/agent/ScopedProcess.d.ts +35 -0
  27. package/dist/agent/ScopedProcess.d.ts.map +1 -0
  28. package/dist/agent/ScopedProcess.js +280 -0
  29. package/dist/agent/ScopedProcess.js.map +1 -0
  30. package/dist/agent/ToolRegistry.d.ts +80 -0
  31. package/dist/agent/ToolRegistry.d.ts.map +1 -0
  32. package/dist/agent/ToolRegistry.js +45 -0
  33. package/dist/agent/ToolRegistry.js.map +1 -0
  34. package/dist/agent/UserInput.d.ts +59 -0
  35. package/dist/agent/UserInput.d.ts.map +1 -0
  36. package/dist/agent/UserInput.js +203 -0
  37. package/dist/agent/UserInput.js.map +1 -0
  38. package/dist/agent/tools/AskUserTool.d.ts +71 -0
  39. package/dist/agent/tools/AskUserTool.d.ts.map +1 -0
  40. package/dist/agent/tools/AskUserTool.js +70 -0
  41. package/dist/agent/tools/AskUserTool.js.map +1 -0
  42. package/dist/agent/tools/DelegateTool.d.ts +49 -0
  43. package/dist/agent/tools/DelegateTool.d.ts.map +1 -0
  44. package/dist/agent/tools/DelegateTool.js +62 -0
  45. package/dist/agent/tools/DelegateTool.js.map +1 -0
  46. package/dist/agent/tools/InspectAttachmentTool.d.ts +25 -0
  47. package/dist/agent/tools/InspectAttachmentTool.d.ts.map +1 -0
  48. package/dist/agent/tools/InspectAttachmentTool.js +129 -0
  49. package/dist/agent/tools/InspectAttachmentTool.js.map +1 -0
  50. package/dist/agent/tools/PythonPackageTool.d.ts +26 -0
  51. package/dist/agent/tools/PythonPackageTool.d.ts.map +1 -0
  52. package/dist/agent/tools/PythonPackageTool.js +105 -0
  53. package/dist/agent/tools/PythonPackageTool.js.map +1 -0
  54. package/dist/agent/tools/ReadFileTool.d.ts +24 -0
  55. package/dist/agent/tools/ReadFileTool.d.ts.map +1 -0
  56. package/dist/agent/tools/ReadFileTool.js +112 -0
  57. package/dist/agent/tools/ReadFileTool.js.map +1 -0
  58. package/dist/agent/tools/ShellExecTool.d.ts +23 -0
  59. package/dist/agent/tools/ShellExecTool.d.ts.map +1 -0
  60. package/dist/agent/tools/ShellExecTool.js +75 -0
  61. package/dist/agent/tools/ShellExecTool.js.map +1 -0
  62. package/dist/agent/tools/WebSearchTool.d.ts +26 -0
  63. package/dist/agent/tools/WebSearchTool.d.ts.map +1 -0
  64. package/dist/agent/tools/WebSearchTool.js +52 -0
  65. package/dist/agent/tools/WebSearchTool.js.map +1 -0
  66. package/dist/agent/tools/WriteFileTool.d.ts +30 -0
  67. package/dist/agent/tools/WriteFileTool.d.ts.map +1 -0
  68. package/dist/agent/tools/WriteFileTool.js +155 -0
  69. package/dist/agent/tools/WriteFileTool.js.map +1 -0
  70. package/dist/app/AppActionResolver.d.ts +15 -0
  71. package/dist/app/AppActionResolver.d.ts.map +1 -0
  72. package/dist/app/AppActionResolver.js +98 -0
  73. package/dist/app/AppActionResolver.js.map +1 -0
  74. package/dist/app/AppSchema.d.ts +83 -0
  75. package/dist/app/AppSchema.d.ts.map +1 -0
  76. package/dist/app/AppSchema.js +17 -0
  77. package/dist/app/AppSchema.js.map +1 -0
  78. package/dist/app/AppStore.d.ts +14 -0
  79. package/dist/app/AppStore.d.ts.map +1 -0
  80. package/dist/app/AppStore.js +146 -0
  81. package/dist/app/AppStore.js.map +1 -0
  82. package/dist/app/AppValidator.d.ts +10 -0
  83. package/dist/app/AppValidator.d.ts.map +1 -0
  84. package/dist/app/AppValidator.js +503 -0
  85. package/dist/app/AppValidator.js.map +1 -0
  86. package/dist/app/SkillAppCompiler.d.ts +5 -0
  87. package/dist/app/SkillAppCompiler.d.ts.map +1 -0
  88. package/dist/app/SkillAppCompiler.js +632 -0
  89. package/dist/app/SkillAppCompiler.js.map +1 -0
  90. package/dist/app/SkillAppDsl.d.ts +93 -0
  91. package/dist/app/SkillAppDsl.d.ts.map +1 -0
  92. package/dist/app/SkillAppDsl.js +72 -0
  93. package/dist/app/SkillAppDsl.js.map +1 -0
  94. package/dist/app/SkillAppInstanceRegistry.d.ts +25 -0
  95. package/dist/app/SkillAppInstanceRegistry.d.ts.map +1 -0
  96. package/dist/app/SkillAppInstanceRegistry.js +218 -0
  97. package/dist/app/SkillAppInstanceRegistry.js.map +1 -0
  98. package/dist/app/SkillAppResolver.d.ts +12 -0
  99. package/dist/app/SkillAppResolver.d.ts.map +1 -0
  100. package/dist/app/SkillAppResolver.js +89 -0
  101. package/dist/app/SkillAppResolver.js.map +1 -0
  102. package/dist/app/SkillAppSchema.d.ts +116 -0
  103. package/dist/app/SkillAppSchema.d.ts.map +1 -0
  104. package/dist/app/SkillAppSchema.js +5 -0
  105. package/dist/app/SkillAppSchema.js.map +1 -0
  106. package/dist/channels/TelegramBridge.d.ts +103 -0
  107. package/dist/channels/TelegramBridge.d.ts.map +1 -0
  108. package/dist/channels/TelegramBridge.js +565 -0
  109. package/dist/channels/TelegramBridge.js.map +1 -0
  110. package/dist/channels/respond.d.ts +46 -0
  111. package/dist/channels/respond.d.ts.map +1 -0
  112. package/dist/channels/respond.js +41 -0
  113. package/dist/channels/respond.js.map +1 -0
  114. package/dist/config/ChatGptTokenRefresh.d.ts +18 -0
  115. package/dist/config/ChatGptTokenRefresh.d.ts.map +1 -0
  116. package/dist/config/ChatGptTokenRefresh.js +63 -0
  117. package/dist/config/ChatGptTokenRefresh.js.map +1 -0
  118. package/dist/config/ConfigBackup.d.ts +20 -0
  119. package/dist/config/ConfigBackup.d.ts.map +1 -0
  120. package/dist/config/ConfigBackup.js +197 -0
  121. package/dist/config/ConfigBackup.js.map +1 -0
  122. package/dist/config/ConfigLoader.d.ts +28 -0
  123. package/dist/config/ConfigLoader.d.ts.map +1 -0
  124. package/dist/config/ConfigLoader.js +335 -0
  125. package/dist/config/ConfigLoader.js.map +1 -0
  126. package/dist/config/ConfigManager.d.ts +55 -0
  127. package/dist/config/ConfigManager.d.ts.map +1 -0
  128. package/dist/config/ConfigManager.js +707 -0
  129. package/dist/config/ConfigManager.js.map +1 -0
  130. package/dist/config/ConfigSchema.d.ts +231 -0
  131. package/dist/config/ConfigSchema.d.ts.map +1 -0
  132. package/dist/config/ConfigSchema.js +15 -0
  133. package/dist/config/ConfigSchema.js.map +1 -0
  134. package/dist/config/GitHubCopilotAuth.d.ts +7 -0
  135. package/dist/config/GitHubCopilotAuth.d.ts.map +1 -0
  136. package/dist/config/GitHubCopilotAuth.js +40 -0
  137. package/dist/config/GitHubCopilotAuth.js.map +1 -0
  138. package/dist/config/MarifoldOpenAICompatProvider.d.ts +39 -0
  139. package/dist/config/MarifoldOpenAICompatProvider.d.ts.map +1 -0
  140. package/dist/config/MarifoldOpenAICompatProvider.js +158 -0
  141. package/dist/config/MarifoldOpenAICompatProvider.js.map +1 -0
  142. package/dist/config/OpenAICompatUrls.d.ts +7 -0
  143. package/dist/config/OpenAICompatUrls.d.ts.map +1 -0
  144. package/dist/config/OpenAICompatUrls.js +47 -0
  145. package/dist/config/OpenAICompatUrls.js.map +1 -0
  146. package/dist/config/ProviderFactory.d.ts +12 -0
  147. package/dist/config/ProviderFactory.d.ts.map +1 -0
  148. package/dist/config/ProviderFactory.js +61 -0
  149. package/dist/config/ProviderFactory.js.map +1 -0
  150. package/dist/config/ProviderInspector.d.ts +46 -0
  151. package/dist/config/ProviderInspector.d.ts.map +1 -0
  152. package/dist/config/ProviderInspector.js +356 -0
  153. package/dist/config/ProviderInspector.js.map +1 -0
  154. package/dist/config/ProviderRegistry.d.ts +19 -0
  155. package/dist/config/ProviderRegistry.d.ts.map +1 -0
  156. package/dist/config/ProviderRegistry.js +301 -0
  157. package/dist/config/ProviderRegistry.js.map +1 -0
  158. package/dist/config/XaiTokenRefresh.d.ts +15 -0
  159. package/dist/config/XaiTokenRefresh.d.ts.map +1 -0
  160. package/dist/config/XaiTokenRefresh.js +73 -0
  161. package/dist/config/XaiTokenRefresh.js.map +1 -0
  162. package/dist/errors/MarifoldError.d.ts +34 -0
  163. package/dist/errors/MarifoldError.d.ts.map +1 -0
  164. package/dist/errors/MarifoldError.js +100 -0
  165. package/dist/errors/MarifoldError.js.map +1 -0
  166. package/dist/images/ImageOptimizer.d.ts +34 -0
  167. package/dist/images/ImageOptimizer.d.ts.map +1 -0
  168. package/dist/images/ImageOptimizer.js +225 -0
  169. package/dist/images/ImageOptimizer.js.map +1 -0
  170. package/dist/index.d.ts +96 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +193 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/memory/MemoryControls.d.ts +26 -0
  175. package/dist/memory/MemoryControls.d.ts.map +1 -0
  176. package/dist/memory/MemoryControls.js +388 -0
  177. package/dist/memory/MemoryControls.js.map +1 -0
  178. package/dist/memory/MemoryStore.d.ts +122 -0
  179. package/dist/memory/MemoryStore.d.ts.map +1 -0
  180. package/dist/memory/MemoryStore.js +1096 -0
  181. package/dist/memory/MemoryStore.js.map +1 -0
  182. package/dist/profiles/ProfileManager.d.ts +139 -0
  183. package/dist/profiles/ProfileManager.d.ts.map +1 -0
  184. package/dist/profiles/ProfileManager.js +475 -0
  185. package/dist/profiles/ProfileManager.js.map +1 -0
  186. package/dist/profiles/ProfileResolver.d.ts +18 -0
  187. package/dist/profiles/ProfileResolver.d.ts.map +1 -0
  188. package/dist/profiles/ProfileResolver.js +280 -0
  189. package/dist/profiles/ProfileResolver.js.map +1 -0
  190. package/dist/runs/RunRegistry.d.ts +140 -0
  191. package/dist/runs/RunRegistry.d.ts.map +1 -0
  192. package/dist/runs/RunRegistry.js +432 -0
  193. package/dist/runs/RunRegistry.js.map +1 -0
  194. package/dist/runtime/MarifoldRuntime.d.ts +244 -0
  195. package/dist/runtime/MarifoldRuntime.d.ts.map +1 -0
  196. package/dist/runtime/MarifoldRuntime.js +1099 -0
  197. package/dist/runtime/MarifoldRuntime.js.map +1 -0
  198. package/dist/runtime/MarifoldTypes.d.ts +70 -0
  199. package/dist/runtime/MarifoldTypes.d.ts.map +1 -0
  200. package/dist/runtime/MarifoldTypes.js +3 -0
  201. package/dist/runtime/MarifoldTypes.js.map +1 -0
  202. package/dist/schedule/ScheduleStore.d.ts +60 -0
  203. package/dist/schedule/ScheduleStore.d.ts.map +1 -0
  204. package/dist/schedule/ScheduleStore.js +212 -0
  205. package/dist/schedule/ScheduleStore.js.map +1 -0
  206. package/dist/schedule/Scheduler.d.ts +28 -0
  207. package/dist/schedule/Scheduler.d.ts.map +1 -0
  208. package/dist/schedule/Scheduler.js +65 -0
  209. package/dist/schedule/Scheduler.js.map +1 -0
  210. package/dist/search/DuckDuckGoBackend.d.ts +18 -0
  211. package/dist/search/DuckDuckGoBackend.d.ts.map +1 -0
  212. package/dist/search/DuckDuckGoBackend.js +37 -0
  213. package/dist/search/DuckDuckGoBackend.js.map +1 -0
  214. package/dist/search/FirecrawlBackend.d.ts +28 -0
  215. package/dist/search/FirecrawlBackend.d.ts.map +1 -0
  216. package/dist/search/FirecrawlBackend.js +76 -0
  217. package/dist/search/FirecrawlBackend.js.map +1 -0
  218. package/dist/search/SearchBackend.d.ts +18 -0
  219. package/dist/search/SearchBackend.d.ts.map +1 -0
  220. package/dist/search/SearchBackend.js +24 -0
  221. package/dist/search/SearchBackend.js.map +1 -0
  222. package/dist/search/createSearchBackend.d.ts +16 -0
  223. package/dist/search/createSearchBackend.d.ts.map +1 -0
  224. package/dist/search/createSearchBackend.js +30 -0
  225. package/dist/search/createSearchBackend.js.map +1 -0
  226. package/dist/sessions/ResponseMetrics.d.ts +17 -0
  227. package/dist/sessions/ResponseMetrics.d.ts.map +1 -0
  228. package/dist/sessions/ResponseMetrics.js +3 -0
  229. package/dist/sessions/ResponseMetrics.js.map +1 -0
  230. package/dist/sessions/SessionResolver.d.ts +135 -0
  231. package/dist/sessions/SessionResolver.d.ts.map +1 -0
  232. package/dist/sessions/SessionResolver.js +1173 -0
  233. package/dist/sessions/SessionResolver.js.map +1 -0
  234. package/dist/skill/BuiltInSkillManager.d.ts +11 -0
  235. package/dist/skill/BuiltInSkillManager.d.ts.map +1 -0
  236. package/dist/skill/BuiltInSkillManager.js +98 -0
  237. package/dist/skill/BuiltInSkillManager.js.map +1 -0
  238. package/dist/skill/SkillInvocation.d.ts +30 -0
  239. package/dist/skill/SkillInvocation.d.ts.map +1 -0
  240. package/dist/skill/SkillInvocation.js +135 -0
  241. package/dist/skill/SkillInvocation.js.map +1 -0
  242. package/dist/skill/SkillSchema.d.ts +37 -0
  243. package/dist/skill/SkillSchema.d.ts.map +1 -0
  244. package/dist/skill/SkillSchema.js +26 -0
  245. package/dist/skill/SkillSchema.js.map +1 -0
  246. package/dist/skill/SkillStore.d.ts +41 -0
  247. package/dist/skill/SkillStore.d.ts.map +1 -0
  248. package/dist/skill/SkillStore.js +184 -0
  249. package/dist/skill/SkillStore.js.map +1 -0
  250. package/dist/skill/SkillTemplater.d.ts +19 -0
  251. package/dist/skill/SkillTemplater.d.ts.map +1 -0
  252. package/dist/skill/SkillTemplater.js +36 -0
  253. package/dist/skill/SkillTemplater.js.map +1 -0
  254. package/dist/skill/SkillValidator.d.ts +10 -0
  255. package/dist/skill/SkillValidator.d.ts.map +1 -0
  256. package/dist/skill/SkillValidator.js +131 -0
  257. package/dist/skill/SkillValidator.js.map +1 -0
  258. package/dist/skill/SkillVars.d.ts +10 -0
  259. package/dist/skill/SkillVars.d.ts.map +1 -0
  260. package/dist/skill/SkillVars.js +65 -0
  261. package/dist/skill/SkillVars.js.map +1 -0
  262. package/dist/skill/index.d.ts +10 -0
  263. package/dist/skill/index.d.ts.map +1 -0
  264. package/dist/skill/index.js +22 -0
  265. package/dist/skill/index.js.map +1 -0
  266. package/dist/skillapp/SkillAppActionResolver.d.ts +13 -0
  267. package/dist/skillapp/SkillAppActionResolver.d.ts.map +1 -0
  268. package/dist/skillapp/SkillAppActionResolver.js +95 -0
  269. package/dist/skillapp/SkillAppActionResolver.js.map +1 -0
  270. package/dist/skillapp/SkillAppSchema.d.ts +79 -0
  271. package/dist/skillapp/SkillAppSchema.d.ts.map +1 -0
  272. package/dist/skillapp/SkillAppSchema.js +20 -0
  273. package/dist/skillapp/SkillAppSchema.js.map +1 -0
  274. package/dist/skillapp/SkillAppStore.d.ts +11 -0
  275. package/dist/skillapp/SkillAppStore.d.ts.map +1 -0
  276. package/dist/skillapp/SkillAppStore.js +98 -0
  277. package/dist/skillapp/SkillAppStore.js.map +1 -0
  278. package/dist/skillapp/SkillAppValidator.d.ts +10 -0
  279. package/dist/skillapp/SkillAppValidator.d.ts.map +1 -0
  280. package/dist/skillapp/SkillAppValidator.js +522 -0
  281. package/dist/skillapp/SkillAppValidator.js.map +1 -0
  282. package/dist/tasks/TaskStore.d.ts +110 -0
  283. package/dist/tasks/TaskStore.d.ts.map +1 -0
  284. package/dist/tasks/TaskStore.js +371 -0
  285. package/dist/tasks/TaskStore.js.map +1 -0
  286. package/dist/util/fetchRetry.d.ts +11 -0
  287. package/dist/util/fetchRetry.d.ts.map +1 -0
  288. package/dist/util/fetchRetry.js +48 -0
  289. package/dist/util/fetchRetry.js.map +1 -0
  290. package/dist/util/idToken.d.ts +12 -0
  291. package/dist/util/idToken.d.ts.map +1 -0
  292. package/dist/util/idToken.js +32 -0
  293. package/dist/util/idToken.js.map +1 -0
  294. package/dist/util/proxy.d.ts +18 -0
  295. package/dist/util/proxy.d.ts.map +1 -0
  296. package/dist/util/proxy.js +28 -0
  297. package/dist/util/proxy.js.map +1 -0
  298. package/dist/workspace/Workspace.d.ts +9 -0
  299. package/dist/workspace/Workspace.d.ts.map +1 -0
  300. package/dist/workspace/Workspace.js +55 -0
  301. package/dist/workspace/Workspace.js.map +1 -0
  302. package/dist/workspace/WorkspaceInitializer.d.ts +40 -0
  303. package/dist/workspace/WorkspaceInitializer.d.ts.map +1 -0
  304. package/dist/workspace/WorkspaceInitializer.js +212 -0
  305. package/dist/workspace/WorkspaceInitializer.js.map +1 -0
  306. package/dist/workspace/WorkspacePaths.d.ts +11 -0
  307. package/dist/workspace/WorkspacePaths.d.ts.map +1 -0
  308. package/dist/workspace/WorkspacePaths.js +82 -0
  309. package/dist/workspace/WorkspacePaths.js.map +1 -0
  310. package/package.json +36 -0
@@ -0,0 +1,1096 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MemoryStore = void 0;
37
+ exports.ensureProfileMemoryFiles = ensureProfileMemoryFiles;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const crypto_1 = require("crypto");
41
+ const MarifoldError_1 = require("../errors/MarifoldError");
42
+ const SAFE_PROFILE_NAME = /^[A-Za-z0-9_-]+$/;
43
+ const CONFLICT_KEY_RE = /^(?:user|preferences|auto_short)(?:\.[a-z0-9][a-z0-9_]{0,39}){1,5}$/;
44
+ const DEFAULT_CONTEXT_LIMIT = 2400;
45
+ const DEFAULT_PRIORITY = 5;
46
+ const NORMAL_PRIORITY_CUTOFF = 3;
47
+ const THINKING_PRIORITY_CUTOFF = 10;
48
+ const SIMPLE_PROMPT_PRIORITY_CUTOFF = 0;
49
+ const JSONL_FILES = {
50
+ user: 'user.jsonl',
51
+ preferences: 'preferences.jsonl',
52
+ auto_short: 'auto_short.jsonl',
53
+ };
54
+ const KIND_ORDER = ['user', 'preferences', 'auto_short'];
55
+ const LEGACY_FILES = [
56
+ { fileName: 'user.md', kind: 'user', priority: 3, reason: 'Legacy user.md fallback' },
57
+ { fileName: 'preferences.md', kind: 'preferences', priority: 3, reason: 'Legacy preferences.md fallback' },
58
+ { fileName: 'notes.md', kind: 'preferences', priority: 3, reason: 'Legacy notes.md fallback' },
59
+ { fileName: 'auto_short.md', kind: 'auto_short', priority: 8, reason: 'Legacy auto_short.md fallback' },
60
+ ];
61
+ const CONFLICT_KEY_ALIASES = {
62
+ 'user.fav_color': 'user.favorite_color',
63
+ 'user.favorite_colour': 'user.favorite_color',
64
+ 'user.preferred_color': 'user.favorite_color',
65
+ 'user.preferred_colour': 'user.favorite_color',
66
+ 'user.color': 'user.favorite_color',
67
+ 'user.colour': 'user.favorite_color',
68
+ 'user.color_preference': 'user.favorite_color',
69
+ 'user.colour_preference': 'user.favorite_color',
70
+ 'user.preferred_name': 'user.name',
71
+ 'user.preferred.name': 'user.name',
72
+ 'preferences.answer_style': 'preferences.reply_style',
73
+ 'preferences.answers_style': 'preferences.reply_style',
74
+ 'preferences.response_style': 'preferences.reply_style',
75
+ 'preferences.responses_style': 'preferences.reply_style',
76
+ 'preferences.communication_style': 'preferences.reply_style',
77
+ 'preferences.conversation_style': 'preferences.reply_style',
78
+ 'preferences.tone_style': 'preferences.reply_style',
79
+ 'preferences.reply_length': 'preferences.reply_style',
80
+ 'preferences.response_length': 'preferences.reply_style',
81
+ 'preferences.preferred_language': 'preferences.language',
82
+ 'preferences.language_preference': 'preferences.language',
83
+ 'auto_short.project_meeting': 'auto_short.project_meeting_time',
84
+ 'auto_short.meeting': 'auto_short.meeting_time',
85
+ };
86
+ const GENERIC_CONFLICT_KEYS = new Set([
87
+ 'user.info',
88
+ 'user.fact',
89
+ 'user.memory',
90
+ 'preferences.info',
91
+ 'preferences.fact',
92
+ 'preferences.memory',
93
+ 'auto_short.info',
94
+ 'auto_short.fact',
95
+ 'auto_short.memory',
96
+ ]);
97
+ function ensureProfileMemoryFiles(profileDir) {
98
+ const memoriesDir = path.join(profileDir, 'memories');
99
+ fs.mkdirSync(memoriesDir, { recursive: true });
100
+ return KIND_ORDER.map(kind => {
101
+ const filePath = path.join(memoriesDir, JSONL_FILES[kind]);
102
+ if (fs.existsSync(filePath))
103
+ return { path: filePath, status: 'kept' };
104
+ fs.writeFileSync(filePath, '');
105
+ return { path: filePath, status: 'created' };
106
+ });
107
+ }
108
+ class MemoryStore {
109
+ profilesDir;
110
+ constructor(profilesDir) {
111
+ this.profilesDir = profilesDir;
112
+ }
113
+ ensureProfile(profile) {
114
+ this.assertSafeProfileName(profile);
115
+ return ensureProfileMemoryFiles(path.join(this.profilesDir, profile));
116
+ }
117
+ remember(profile, kind, text, options = {}) {
118
+ this.assertSafeProfileName(profile);
119
+ const trimmed = text.trim();
120
+ if (!trimmed)
121
+ throw MarifoldError_1.MarifoldError.memoryInvalid('Memory text cannot be empty.', profile);
122
+ const result = this.saveEntry(profile, entryFromRecord({
123
+ kind,
124
+ text: trimmed,
125
+ source: options.source ?? 'user_direct',
126
+ source_type: options.sourceType ?? 'user',
127
+ scope: options.scope ?? 'profile',
128
+ scope_id: options.scopeId,
129
+ session_id: options.sessionId,
130
+ task_id: options.taskId,
131
+ conflict_key: options.conflictKey,
132
+ priority: options.priority ?? manualPriority(kind),
133
+ confidence: options.confidence ?? 1,
134
+ stability: options.stability ?? manualStability(kind),
135
+ evidence: options.evidence,
136
+ reason: options.reason ?? manualReason(kind),
137
+ expires_at: options.expiresAt,
138
+ status: options.status,
139
+ }, kind, {
140
+ source: options.source ?? 'user_direct',
141
+ sourceType: options.sourceType ?? 'user',
142
+ priority: options.priority ?? manualPriority(kind),
143
+ confidence: options.confidence ?? 1,
144
+ scope: options.scope ?? 'profile',
145
+ }, profile));
146
+ return {
147
+ profile,
148
+ kind: result.entry.kind,
149
+ path: result.path,
150
+ entry: result.entry,
151
+ created: result.created,
152
+ };
153
+ }
154
+ save(profile, inputs, options = {}) {
155
+ this.assertSafeProfileName(profile);
156
+ let created = 0;
157
+ let skipped = 0;
158
+ const entries = [];
159
+ const paths = new Set();
160
+ for (const input of inputs) {
161
+ const text = typeof input.text === 'string' ? input.text.trim() : '';
162
+ if (!text)
163
+ continue;
164
+ const entry = entryFromRecord({
165
+ kind: input.kind,
166
+ text,
167
+ source: input.source,
168
+ source_type: input.sourceType,
169
+ scope: input.scope,
170
+ scope_id: input.scopeId,
171
+ session_id: options.sessionId,
172
+ task_id: options.taskId,
173
+ conflict_key: input.conflictKey,
174
+ priority: input.priority,
175
+ confidence: input.confidence,
176
+ stability: input.stability,
177
+ evidence: input.evidence,
178
+ reason: input.reason,
179
+ expires_at: input.expiresAt,
180
+ status: input.status,
181
+ }, input.kind, {
182
+ source: input.source ?? 'model_inferred',
183
+ sourceType: input.sourceType,
184
+ priority: DEFAULT_PRIORITY,
185
+ confidence: 0.6,
186
+ scope: input.scope ?? 'profile',
187
+ }, profile);
188
+ if (!entry)
189
+ continue;
190
+ const result = this.saveEntry(profile, entry);
191
+ if (result.created)
192
+ created += 1;
193
+ else
194
+ skipped += 1;
195
+ entries.push(result.entry);
196
+ paths.add(result.path);
197
+ }
198
+ return { profile, created, skipped, entries, paths: [...paths] };
199
+ }
200
+ applySavePayloads(profile, payloads, options = {}) {
201
+ return this.save(profile, payloads.flatMap(parseSavePayload), options);
202
+ }
203
+ applyForgetPayloads(profile, payloads) {
204
+ this.assertSafeProfileName(profile);
205
+ let count = 0;
206
+ const paths = new Set();
207
+ const queries = [];
208
+ for (const query of payloads.flatMap(parseForgetPayload)) {
209
+ const result = this.forget(profile, query.query, query.kind);
210
+ queries.push(result.query);
211
+ count += result.count;
212
+ for (const filePath of result.paths)
213
+ paths.add(filePath);
214
+ }
215
+ return { profile, query: queries.join(', '), count, paths: [...paths] };
216
+ }
217
+ forget(profile, query, kind) {
218
+ return this.updateMatching(profile, query, entry => ({
219
+ ...entry,
220
+ status: 'superseded',
221
+ updated_at: utcNow(),
222
+ }), kind);
223
+ }
224
+ delete(profile, query, kind) {
225
+ this.assertSafeProfileName(profile);
226
+ const needle = this.normalizeQuery(profile, query);
227
+ this.ensureProfile(profile);
228
+ const normalizedKind = kind ? normalizeKind(kind) : undefined;
229
+ let count = 0;
230
+ const paths = [];
231
+ for (const memoryKind of KIND_ORDER) {
232
+ if (normalizedKind && normalizedKind !== memoryKind)
233
+ continue;
234
+ const filePath = this.jsonlPath(profile, memoryKind);
235
+ if (!fs.existsSync(filePath))
236
+ continue;
237
+ const lines = readJsonlLines(filePath, memoryKind);
238
+ const next = lines.filter(line => {
239
+ if (line.entry && entryMatchesQuery(line.entry, needle, normalizedKind)) {
240
+ count += 1;
241
+ return false;
242
+ }
243
+ return true;
244
+ });
245
+ if (next.length !== lines.length) {
246
+ writeJsonlLines(filePath, next);
247
+ paths.push(filePath);
248
+ }
249
+ }
250
+ return { profile, query: needle, count, paths };
251
+ }
252
+ /** Supersede exactly one entry by id (a per-row Forget — no fuzzy matching,
253
+ * unlike `forget`'s query semantics). */
254
+ forgetById(profile, id) {
255
+ return this.mutateById(profile, id, entry => ({
256
+ ...entry,
257
+ status: 'superseded',
258
+ updated_at: utcNow(),
259
+ }));
260
+ }
261
+ /** Permanently remove exactly one entry by id (a per-row Delete). */
262
+ deleteById(profile, id) {
263
+ return this.mutateById(profile, id, () => undefined);
264
+ }
265
+ /** Exact-id mutation across all kinds: update returning undefined removes the line. */
266
+ mutateById(profile, id, update) {
267
+ this.assertSafeProfileName(profile);
268
+ this.ensureProfile(profile);
269
+ let count = 0;
270
+ const paths = [];
271
+ for (const memoryKind of KIND_ORDER) {
272
+ const filePath = this.jsonlPath(profile, memoryKind);
273
+ if (!fs.existsSync(filePath))
274
+ continue;
275
+ let changed = false;
276
+ const lines = readJsonlLines(filePath, memoryKind).flatMap(line => {
277
+ if (line.entry?.id !== id)
278
+ return [line];
279
+ count += 1;
280
+ changed = true;
281
+ const updated = update(line.entry);
282
+ return updated === undefined ? [] : [{ entry: updated, raw: line.raw }];
283
+ });
284
+ if (changed) {
285
+ writeJsonlLines(filePath, lines);
286
+ paths.push(filePath);
287
+ }
288
+ }
289
+ return { profile, query: id, count, paths };
290
+ }
291
+ listEntries(profile) {
292
+ this.assertSafeProfileName(profile);
293
+ this.ensureProfile(profile);
294
+ const entries = [];
295
+ for (const kind of KIND_ORDER) {
296
+ entries.push(...this.readEntriesFromFile(this.jsonlPath(profile, kind), kind));
297
+ }
298
+ return entries;
299
+ }
300
+ listPromptMemory(profile, options = {}) {
301
+ const limit = options.limit ?? 50;
302
+ const contextLimit = options.contextLimit ?? DEFAULT_CONTEXT_LIMIT;
303
+ const cutoff = isSimpleMemoryPrompt(options.prompt ?? '')
304
+ ? SIMPLE_PROMPT_PRIORITY_CUTOFF
305
+ : options.thinking
306
+ ? THINKING_PRIORITY_CUTOFF
307
+ : NORMAL_PRIORITY_CUTOFF;
308
+ const promptTokens = tokens(options.prompt ?? '');
309
+ const nowTs = Date.now() / 1000;
310
+ let candidates = [
311
+ ...this.listEntries(profile),
312
+ ...this.readLegacyEntries(profile),
313
+ ].filter(entry => (entry.status === 'active'
314
+ && !isExpired(entry, nowTs)
315
+ && entry.priority <= cutoff));
316
+ candidates.sort((a, b) => compareMemoryRank(a, b, promptTokens));
317
+ candidates = candidates.slice(0, Math.max(0, limit));
318
+ if (contextLimit > 0) {
319
+ const selected = [];
320
+ for (const entry of candidates) {
321
+ const trial = [...selected, entry];
322
+ if (renderPromptMemory(trial).join('\n\n').length <= contextLimit)
323
+ selected.push(entry);
324
+ }
325
+ candidates = selected;
326
+ }
327
+ return renderPromptMemory(candidates);
328
+ }
329
+ trimShortTerm(profile, sizeLimit) {
330
+ this.assertSafeProfileName(profile);
331
+ if (sizeLimit <= 0)
332
+ return;
333
+ this.ensureProfile(profile);
334
+ const filePath = this.jsonlPath(profile, 'auto_short');
335
+ const lines = readJsonlLines(filePath, 'auto_short');
336
+ const entries = lines
337
+ .map(line => line.entry)
338
+ .filter((entry) => entry !== undefined);
339
+ if (serializedJsonlLength(entries) <= sizeLimit)
340
+ return;
341
+ let keep = entries.filter(entry => !isExpired(entry));
342
+ if (keep.length === 0 && entries.length > 0) {
343
+ keep = [entries.reduce((best, entry) => entry.priority < best.priority ? entry : best, entries[0])];
344
+ }
345
+ while (keep.length > 1 && serializedJsonlLength(keep) > sizeLimit) {
346
+ const removable = keep.filter(entry => entry.priority !== 0);
347
+ if (removable.length === 0)
348
+ break;
349
+ const victim = removable.reduce((worst, entry) => compareTrimRank(entry, worst) > 0 ? entry : worst, removable[0]);
350
+ keep = keep.filter(entry => entry.id !== victim.id);
351
+ }
352
+ if (serializedJsonlLength(keep) > sizeLimit) {
353
+ keep = keep.filter(entry => entry.priority === 0);
354
+ if (keep.length === 0 && entries.length > 0)
355
+ keep = [entries[entries.length - 1]];
356
+ }
357
+ const keepIds = new Set(keep.map(entry => entry.id));
358
+ writeJsonlLines(filePath, lines.filter(line => !line.entry || keepIds.has(line.entry.id)));
359
+ }
360
+ saveEntry(profile, entry) {
361
+ if (!entry)
362
+ throw MarifoldError_1.MarifoldError.memoryInvalid('Memory entry is invalid.', profile);
363
+ this.ensureProfile(profile);
364
+ const filePath = this.jsonlPath(profile, entry.kind);
365
+ const lines = readJsonlLines(filePath, entry.kind);
366
+ const merge = mergeEntry(lines, entry);
367
+ writeJsonlLines(filePath, merge.lines);
368
+ return { created: merge.created, entry: merge.entry, path: filePath };
369
+ }
370
+ updateMatching(profile, query, update, kind) {
371
+ this.assertSafeProfileName(profile);
372
+ const needle = this.normalizeQuery(profile, query);
373
+ this.ensureProfile(profile);
374
+ const normalizedKind = kind ? normalizeKind(kind) : undefined;
375
+ let count = 0;
376
+ const paths = [];
377
+ for (const memoryKind of KIND_ORDER) {
378
+ if (normalizedKind && normalizedKind !== memoryKind)
379
+ continue;
380
+ const filePath = this.jsonlPath(profile, memoryKind);
381
+ if (!fs.existsSync(filePath))
382
+ continue;
383
+ let changed = false;
384
+ const lines = readJsonlLines(filePath, memoryKind).map(line => {
385
+ if (line.entry?.status === 'active' && entryMatchesQuery(line.entry, needle, normalizedKind)) {
386
+ count += 1;
387
+ changed = true;
388
+ return { entry: update(line.entry), raw: line.raw };
389
+ }
390
+ return line;
391
+ });
392
+ if (changed) {
393
+ writeJsonlLines(filePath, lines);
394
+ paths.push(filePath);
395
+ }
396
+ }
397
+ return { profile, query: needle, count, paths };
398
+ }
399
+ readEntriesFromFile(filePath, fallbackKind) {
400
+ return readJsonlLines(filePath, fallbackKind)
401
+ .map(line => line.entry)
402
+ .filter((entry) => entry !== undefined);
403
+ }
404
+ readLegacyEntries(profile) {
405
+ const memoriesDir = this.memoriesDir(profile);
406
+ const entries = [];
407
+ for (const legacy of LEGACY_FILES) {
408
+ const filePath = path.join(memoriesDir, legacy.fileName);
409
+ if (!fs.existsSync(filePath))
410
+ continue;
411
+ const now = utcNow();
412
+ let currentDate = '';
413
+ for (const rawLine of fs.readFileSync(filePath, 'utf-8').split(/\r?\n/)) {
414
+ const trimmed = rawLine.trim();
415
+ if (!trimmed)
416
+ continue;
417
+ const dateMatch = /^##\s+(\d{4}-\d{2}-\d{2})/.exec(trimmed);
418
+ if (dateMatch) {
419
+ currentDate = dateMatch[1];
420
+ continue;
421
+ }
422
+ if (trimmed.startsWith('#'))
423
+ continue;
424
+ entries.push({
425
+ id: `legacy-${(0, crypto_1.randomUUID)()}`,
426
+ kind: legacy.kind,
427
+ text: currentDate ? `${currentDate}: ${trimmed}` : trimmed,
428
+ priority: legacy.priority,
429
+ confidence: 1,
430
+ stability: legacy.kind === 'auto_short' ? 'session' : 'stable',
431
+ status: 'active',
432
+ source: 'system',
433
+ source_type: 'system',
434
+ scope: 'profile',
435
+ reason: legacy.reason,
436
+ created_at: now,
437
+ updated_at: now,
438
+ last_seen_at: now,
439
+ });
440
+ }
441
+ }
442
+ return dedupeEntries(entries);
443
+ }
444
+ jsonlPath(profile, kind) {
445
+ return path.join(this.memoriesDir(profile), JSONL_FILES[kind]);
446
+ }
447
+ memoriesDir(profile) {
448
+ this.assertSafeProfileName(profile);
449
+ return path.join(this.profilesDir, profile, 'memories');
450
+ }
451
+ normalizeQuery(profile, query) {
452
+ const needle = normalizeText(query);
453
+ if (!needle)
454
+ throw MarifoldError_1.MarifoldError.memoryInvalid('Memory query cannot be empty.', profile);
455
+ return needle;
456
+ }
457
+ assertSafeProfileName(profile) {
458
+ if (!SAFE_PROFILE_NAME.test(profile)) {
459
+ throw MarifoldError_1.MarifoldError.profileInvalid(`Invalid profile name '${profile}'. Use letters, numbers, underscores, or hyphens.`, profile);
460
+ }
461
+ }
462
+ }
463
+ exports.MemoryStore = MemoryStore;
464
+ function readJsonlLines(filePath, fallbackKind) {
465
+ if (!fs.existsSync(filePath))
466
+ return [];
467
+ return fs.readFileSync(filePath, 'utf-8')
468
+ .split(/\r?\n/)
469
+ .filter(line => line.trim().length > 0)
470
+ .map(raw => {
471
+ try {
472
+ const parsed = JSON.parse(raw);
473
+ const entry = entryFromRecord(parsed, fallbackKind, {
474
+ source: 'manual',
475
+ priority: DEFAULT_PRIORITY,
476
+ confidence: 0.6,
477
+ scope: 'profile',
478
+ });
479
+ return entry ? { raw, entry } : { raw };
480
+ }
481
+ catch {
482
+ return { raw };
483
+ }
484
+ });
485
+ }
486
+ function entryFromRecord(raw, fallbackKind, defaults, profile = 'default') {
487
+ let kind = normalizeKind(raw.kind ?? raw.target) ?? fallbackKind;
488
+ const text = stringValue(raw.text ?? raw.content);
489
+ if (!text)
490
+ return undefined;
491
+ if ((kind === 'user' || kind === 'preferences') && looksTimeSensitive(text)) {
492
+ kind = 'auto_short';
493
+ }
494
+ else if (kind === 'user' && looksResponsePreference(text)) {
495
+ kind = 'preferences';
496
+ }
497
+ const now = utcNow();
498
+ const priority = normalizePriority(raw.priority, defaultPriority(kind, defaults.priority), kind, text, raw);
499
+ const confidence = clampNumber(raw.confidence, defaults.confidence, 0, 1);
500
+ const stability = normalizeStability(raw.stability, defaultStability(kind));
501
+ const source = normalizeSource(raw.source, defaults.source);
502
+ const sourceType = normalizeSourceType(raw.source_type, defaults.sourceType ?? sourceTypeFromSource(source));
503
+ const scope = normalizeScope(raw.scope, defaults.scope);
504
+ const status = raw.status === 'superseded' ? 'superseded' : 'active';
505
+ const rawConflictValue = raw.conflict_key ?? raw.conflicts_with;
506
+ const rawConflictProvided = Boolean(stringValue(rawConflictValue));
507
+ let conflictKey = normalizeConflictKey(rawConflictValue);
508
+ if (conflictKey && !conflictKey.startsWith(`${kind}.`))
509
+ conflictKey = undefined;
510
+ if (!conflictKey && !rawConflictProvided && kind === 'preferences' && looksResponsePreference(text)) {
511
+ conflictKey = 'preferences.reply_style';
512
+ }
513
+ if (!conflictKey && !rawConflictProvided && kind === 'auto_short' && /\bmeeting\b/i.test(text)) {
514
+ conflictKey = /\bproject meeting\b/i.test(text) ? 'auto_short.project_meeting_time' : 'auto_short.meeting_time';
515
+ }
516
+ const id = stringValue(raw.id) || (0, crypto_1.randomUUID)();
517
+ const createdAt = stringValue(raw.created_at) || now;
518
+ const updatedAt = stringValue(raw.updated_at) || now;
519
+ const lastSeenAt = stringValue(raw.last_seen_at) || updatedAt;
520
+ const supersedes = Array.isArray(raw.supersedes)
521
+ ? raw.supersedes.map(item => String(item).trim()).filter(Boolean)
522
+ : [];
523
+ return {
524
+ ...raw,
525
+ id,
526
+ kind,
527
+ text,
528
+ priority,
529
+ confidence,
530
+ stability,
531
+ status,
532
+ source,
533
+ source_type: sourceType,
534
+ scope,
535
+ created_at: createdAt,
536
+ updated_at: updatedAt,
537
+ last_seen_at: lastSeenAt,
538
+ ...(stringValue(raw.session_id) ? { session_id: stringValue(raw.session_id) } : {}),
539
+ ...(stringValue(raw.task_id) ? { task_id: stringValue(raw.task_id) } : {}),
540
+ ...(stringValue(raw.scope_id) ? { scope_id: stringValue(raw.scope_id) } : {}),
541
+ ...(conflictKey ? { conflict_key: conflictKey } : {}),
542
+ ...(supersedes.length > 0 ? { supersedes } : {}),
543
+ ...(stringValue(raw.evidence) ? { evidence: stringValue(raw.evidence) } : {}),
544
+ ...(stringValue(raw.reason) ? { reason: stringValue(raw.reason) } : {}),
545
+ ...(stringValue(raw.expires_at) ? { expires_at: stringValue(raw.expires_at) } : {}),
546
+ };
547
+ }
548
+ function normalizePriority(value, defaultValue, kind, text, raw) {
549
+ let priority = clampInteger(value, defaultValue, 0, 10);
550
+ const confidence = clampNumber(raw.confidence, 0.6, 0, 1);
551
+ const stability = normalizeStability(raw.stability, defaultStability(kind));
552
+ const conflictKey = normalizeConflictKey(raw.conflict_key ?? raw.conflicts_with);
553
+ const priorityZeroAllowed = (kind === 'user'
554
+ && confidence >= 0.9
555
+ && stability === 'stable'
556
+ && (conflictKey === 'user.name' || looksIdentityNameFact(text)));
557
+ if (priority === 0 && !priorityZeroAllowed) {
558
+ if (kind === 'preferences')
559
+ priority = 2;
560
+ else if (kind === 'auto_short')
561
+ priority = 3;
562
+ else
563
+ priority = 1;
564
+ }
565
+ return priority;
566
+ }
567
+ function parseSavePayload(payload) {
568
+ let parsed;
569
+ try {
570
+ parsed = JSON.parse(payload);
571
+ }
572
+ catch {
573
+ return [];
574
+ }
575
+ return memoryInputsFromValue(parsed);
576
+ }
577
+ function memoryInputsFromValue(value) {
578
+ if (!isRecord(value))
579
+ return [];
580
+ const memories = value.memories;
581
+ if (Array.isArray(memories)) {
582
+ return memories
583
+ .map(item => memoryInputFromRecord(item))
584
+ .filter((input) => input !== undefined);
585
+ }
586
+ const direct = memoryInputFromRecord(value);
587
+ if (direct)
588
+ return [direct];
589
+ const legacy = [];
590
+ for (const [key, kind] of [
591
+ ['user', 'user'],
592
+ ['preferences', 'preferences'],
593
+ ['pref', 'preferences'],
594
+ ['notes', 'preferences'],
595
+ ['auto_short', 'auto_short'],
596
+ ['short', 'auto_short'],
597
+ ]) {
598
+ const text = stringValue(value[key]);
599
+ if (text)
600
+ legacy.push({ kind, text, source: 'model_inferred' });
601
+ }
602
+ return legacy;
603
+ }
604
+ function memoryInputFromRecord(value) {
605
+ if (!isRecord(value))
606
+ return undefined;
607
+ const kind = normalizeKind(value.kind ?? value.target);
608
+ const text = stringValue(value.text ?? value.content);
609
+ if (!kind || !text)
610
+ return undefined;
611
+ return {
612
+ kind,
613
+ text,
614
+ source: stringValue(value.source) || 'model_inferred',
615
+ sourceType: value.source_type === undefined ? undefined : normalizeSourceType(value.source_type, undefined),
616
+ scope: normalizeScope(value.scope, 'profile'),
617
+ scopeId: stringValue(value.scope_id),
618
+ conflictKey: stringValue(value.conflict_key ?? value.conflicts_with),
619
+ priority: finiteNumber(value.priority),
620
+ confidence: finiteNumber(value.confidence),
621
+ stability: stringValue(value.stability),
622
+ evidence: stringValue(value.evidence),
623
+ reason: stringValue(value.reason),
624
+ expiresAt: stringValue(value.expires_at),
625
+ status: value.status === 'superseded' ? 'superseded' : 'active',
626
+ };
627
+ }
628
+ function parseForgetPayload(payload) {
629
+ let parsed;
630
+ try {
631
+ parsed = JSON.parse(payload);
632
+ }
633
+ catch {
634
+ return [];
635
+ }
636
+ return forgetQueriesFromValue(parsed);
637
+ }
638
+ function forgetQueriesFromValue(value) {
639
+ if (typeof value === 'string')
640
+ return value.trim() ? [{ query: value.trim() }] : [];
641
+ if (!isRecord(value))
642
+ return [];
643
+ const rawItems = value.forget ?? value.queries ?? value.items;
644
+ if (Array.isArray(rawItems))
645
+ return rawItems.flatMap(forgetQueriesFromValue);
646
+ const query = stringValue(value.query ?? value.conflict_key ?? value.text);
647
+ const kind = normalizeKind(value.kind);
648
+ return query ? [{ query, ...(kind ? { kind } : {}) }] : [];
649
+ }
650
+ function mergeEntry(lines, incoming) {
651
+ const now = utcNow();
652
+ incoming.updated_at = now;
653
+ incoming.last_seen_at = now;
654
+ const incomingKey = entryKey(incoming);
655
+ for (const line of lines) {
656
+ if (!line.entry || entryKey(line.entry) !== incomingKey)
657
+ continue;
658
+ line.entry = mergeDuplicate(line.entry, incoming, now);
659
+ return { lines, created: false, entry: line.entry };
660
+ }
661
+ const groups = conflictGroups(incoming);
662
+ if (groups.size > 0) {
663
+ const conflicting = lines
664
+ .map(line => line.entry)
665
+ .filter((entry) => Boolean(entry && intersects(conflictGroups(entry), groups)));
666
+ preserveMeetingDate(incoming, conflicting);
667
+ const superseded = [];
668
+ for (const entry of conflicting) {
669
+ if (entry.status === 'active') {
670
+ entry.status = 'superseded';
671
+ entry.updated_at = now;
672
+ superseded.push(entry.id);
673
+ }
674
+ }
675
+ if (superseded.length > 0)
676
+ incoming.supersedes = sortedUnique([...(incoming.supersedes ?? []), ...superseded]);
677
+ }
678
+ return {
679
+ lines: [...lines, { raw: '', entry: incoming }],
680
+ created: true,
681
+ entry: incoming,
682
+ };
683
+ }
684
+ function mergeDuplicate(existing, incoming, now) {
685
+ return {
686
+ ...existing,
687
+ priority: Math.min(existing.priority, incoming.priority),
688
+ confidence: Math.max(existing.confidence, incoming.confidence),
689
+ stability: incoming.stability === 'stable' || !isStability(existing.stability) ? incoming.stability : existing.stability,
690
+ source: incoming.source === 'user_direct' ? incoming.source : existing.source,
691
+ source_type: incoming.source_type === 'user' ? incoming.source_type : existing.source_type,
692
+ scope: incoming.scope ?? existing.scope,
693
+ status: 'active',
694
+ updated_at: now,
695
+ last_seen_at: now,
696
+ ...(incoming.session_id ? { session_id: incoming.session_id } : {}),
697
+ ...(incoming.task_id ? { task_id: incoming.task_id } : {}),
698
+ ...(incoming.scope_id ? { scope_id: incoming.scope_id } : {}),
699
+ ...(incoming.conflict_key ? { conflict_key: incoming.conflict_key } : {}),
700
+ ...(incoming.evidence ? { evidence: incoming.evidence } : {}),
701
+ ...(incoming.reason ? { reason: incoming.reason } : {}),
702
+ ...(incoming.expires_at ? { expires_at: incoming.expires_at } : {}),
703
+ supersedes: sortedUnique([...(existing.supersedes ?? []), ...(incoming.supersedes ?? [])]),
704
+ };
705
+ }
706
+ function writeJsonlLines(filePath, lines) {
707
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
708
+ const text = lines
709
+ .map(line => line.entry ? JSON.stringify(line.entry) : line.raw)
710
+ .join('\n');
711
+ atomicWrite(filePath, text ? `${text}\n` : '');
712
+ }
713
+ function atomicWrite(filePath, content) {
714
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
715
+ const tmpPath = path.join(path.dirname(filePath), `.${path.basename(filePath)}.${(0, crypto_1.randomUUID)()}.tmp`);
716
+ fs.writeFileSync(tmpPath, content);
717
+ fs.renameSync(tmpPath, filePath);
718
+ }
719
+ function renderPromptMemory(entries) {
720
+ const groups = [
721
+ { header: '## Important User Memory', entries: entries.filter(entry => entry.kind === 'user') },
722
+ {
723
+ header: '## Preferences',
724
+ entries: entries.filter(entry => entry.kind === 'preferences' && entry.reason !== 'Legacy notes.md fallback'),
725
+ },
726
+ {
727
+ header: '## Legacy Notes Memory (read-only, lower authority than approved preferences)',
728
+ entries: entries.filter(entry => entry.kind === 'preferences' && entry.reason === 'Legacy notes.md fallback'),
729
+ },
730
+ { header: '## Current Context', entries: entries.filter(entry => entry.kind === 'auto_short') },
731
+ ];
732
+ return groups.flatMap(group => {
733
+ const lines = group.entries.map(formatMemoryEntry).filter(Boolean);
734
+ return lines.length > 0 ? [`${group.header}\n\n${lines.join('\n')}`] : [];
735
+ });
736
+ }
737
+ function formatMemoryEntry(entry) {
738
+ let line = formatBullet(entry.text);
739
+ if (!line || entry.kind !== 'auto_short')
740
+ return line;
741
+ const dateText = meetingDate(entry.text);
742
+ if (dateText) {
743
+ line += ` (When answering about this, include the date word exactly: ${dateText}.)`;
744
+ }
745
+ return line;
746
+ }
747
+ function formatBullet(text) {
748
+ const stripped = text.trim();
749
+ if (!stripped)
750
+ return '';
751
+ if (stripped.includes('\n') || stripped.startsWith('- ') || stripped.startsWith('* '))
752
+ return stripped;
753
+ return `- ${stripped}`;
754
+ }
755
+ function compareMemoryRank(a, b, promptTokens) {
756
+ const ar = memoryRank(a, promptTokens);
757
+ const br = memoryRank(b, promptTokens);
758
+ for (let index = 0; index < ar.length; index += 1) {
759
+ if (ar[index] !== br[index])
760
+ return ar[index] - br[index];
761
+ }
762
+ return 0;
763
+ }
764
+ function memoryRank(entry, promptTokens) {
765
+ const relevance = promptTokens.size > 0 ? intersectionSize(tokens(entry.text), promptTokens) : 0;
766
+ return [
767
+ entry.priority,
768
+ -relevance,
769
+ -entry.confidence,
770
+ -timestamp(entry.last_seen_at || entry.updated_at || entry.created_at),
771
+ ];
772
+ }
773
+ function compareTrimRank(a, b) {
774
+ const ar = trimRank(a);
775
+ const br = trimRank(b);
776
+ for (let index = 0; index < ar.length; index += 1) {
777
+ if (ar[index] !== br[index])
778
+ return ar[index] - br[index];
779
+ }
780
+ return 0;
781
+ }
782
+ function trimRank(entry) {
783
+ return [
784
+ entry.priority === 0 ? 0 : 1,
785
+ entry.priority,
786
+ entry.confidence,
787
+ timestamp(entry.last_seen_at || entry.updated_at || entry.created_at),
788
+ ];
789
+ }
790
+ function entryMatchesQuery(entry, query, kind) {
791
+ if (kind && entry.kind !== kind)
792
+ return false;
793
+ const conflictKey = normalizeConflictKey(query);
794
+ const queryText = normalizeText(query);
795
+ const queryTokens = tokens(queryText);
796
+ const text = normalizeText(entry.text);
797
+ const textTokens = tokens(entry.text);
798
+ return Boolean(entry.id === query
799
+ || normalizeText(entry.id).includes(queryText)
800
+ || (conflictKey && conflictGroups(entry).has(conflictKey))
801
+ || (queryText && text.includes(queryText))
802
+ || (queryTokens.size > 0 && isSubset(queryTokens, textTokens)));
803
+ }
804
+ function conflictGroups(entry) {
805
+ const groups = new Set();
806
+ const conflictKey = normalizeConflictKey(entry.conflict_key);
807
+ if (conflictKey) {
808
+ groups.add(conflictKey);
809
+ if (conflictKey.endsWith('project_meeting_time'))
810
+ groups.add(`${entry.kind}:meeting:project`);
811
+ else if (conflictKey.endsWith('meeting_time'))
812
+ groups.add(`${entry.kind}:meeting:general`);
813
+ }
814
+ const inferred = inferredConflictGroup(entry);
815
+ if (inferred) {
816
+ groups.add(inferred);
817
+ if (inferred.includes(':meeting:')) {
818
+ const parts = inferred.split(':');
819
+ if (parts.length >= 4)
820
+ groups.add(`${entry.kind}:meeting:${parts[parts.length - 1]}`);
821
+ }
822
+ }
823
+ return groups;
824
+ }
825
+ function inferredConflictGroup(entry) {
826
+ const normalized = normalizeText(entry.text);
827
+ if (entry.kind === 'user') {
828
+ if (looksIdentityNameFact(entry.text))
829
+ return 'user.name';
830
+ const favoriteKey = favoriteConflictKeyFromText(normalized);
831
+ if (favoriteKey)
832
+ return favoriteKey;
833
+ }
834
+ if (entry.kind === 'preferences' && looksResponsePreference(entry.text))
835
+ return 'preferences.reply_style';
836
+ if (normalized.includes('meeting') && /\b\d{1,2}(?::\d{2})?\s*(?:a\.?m\.?|p\.?m\.?|am|pm)\b/.test(normalized)) {
837
+ const date = meetingDate(entry.text) || 'unspecified';
838
+ const topic = normalized.includes('project meeting') ? 'project' : 'general';
839
+ return `${entry.kind}:meeting:${date}:${topic}`;
840
+ }
841
+ return undefined;
842
+ }
843
+ function favoriteConflictKeyFromText(text) {
844
+ const patterns = [
845
+ /\b(?:the\s+)?user(?:'s)?\s+favou?rite\s+([a-z0-9][a-z0-9 _-]{0,40}?)\s+(?:is|=|:)\b/,
846
+ /\bmy\s+favou?rite\s+([a-z0-9][a-z0-9 _-]{0,40}?)\s+(?:is|=|:)\b/,
847
+ ];
848
+ for (const pattern of patterns) {
849
+ const match = pattern.exec(text);
850
+ if (!match)
851
+ continue;
852
+ const slot = slotKey(match[1]);
853
+ if (slot)
854
+ return normalizeConflictKey(`user.favorite_${slot}`);
855
+ }
856
+ return undefined;
857
+ }
858
+ function preserveMeetingDate(incoming, conflicts) {
859
+ if (incoming.kind !== 'auto_short')
860
+ return;
861
+ const incomingText = normalizeText(incoming.text);
862
+ if (!incomingText.includes('meeting') || meetingDate(incoming.text))
863
+ return;
864
+ for (const entry of conflicts) {
865
+ const dateText = meetingDate(entry.text);
866
+ if (!dateText)
867
+ continue;
868
+ incoming.text = incoming.text.replace(/\b(meeting)(\s+at\s+)/i, `$1 ${dateText}$2`);
869
+ return;
870
+ }
871
+ }
872
+ function normalizeConflictKey(value) {
873
+ const raw = stringValue(value);
874
+ if (!raw)
875
+ return undefined;
876
+ let key = raw
877
+ .toLowerCase()
878
+ .replace(/-/g, '_')
879
+ .replace(/:/g, '.')
880
+ .replace(/\s+/g, '_')
881
+ .replace(/\.+/g, '.')
882
+ .replace(/^\.|\.$/g, '');
883
+ key = CONFLICT_KEY_ALIASES[key] ?? key;
884
+ if (key.startsWith('user.preferred_') && key !== 'user.preferred_name') {
885
+ key = `user.favorite_${key.slice('user.preferred_'.length)}`;
886
+ }
887
+ if (key.startsWith('user.fav_'))
888
+ key = `user.favorite_${key.slice('user.fav_'.length)}`;
889
+ key = key.replace(/favourite/g, 'favorite').replace(/colour/g, 'color');
890
+ key = CONFLICT_KEY_ALIASES[key] ?? key;
891
+ if (GENERIC_CONFLICT_KEYS.has(key))
892
+ return undefined;
893
+ return CONFLICT_KEY_RE.test(key) ? key : undefined;
894
+ }
895
+ function normalizeKind(value) {
896
+ if (typeof value !== 'string')
897
+ return undefined;
898
+ const normalized = value.trim().toLowerCase().replace(/-/g, '_');
899
+ if (normalized === 'user' || normalized === 'preferences' || normalized === 'auto_short')
900
+ return normalized;
901
+ if (normalized === 'pref' || normalized === 'prefs' || normalized === 'preference' || normalized === 'notes')
902
+ return 'preferences';
903
+ if (normalized === 'note' || normalized === 'short' || normalized === 'short_term' || normalized === 'session' || normalized === 'current' || normalized === 'auto')
904
+ return 'auto_short';
905
+ return undefined;
906
+ }
907
+ function normalizeStability(value, fallback) {
908
+ return isStability(value) ? value : fallback;
909
+ }
910
+ function isStability(value) {
911
+ return value === 'stable' || value === 'evolving' || value === 'session' || value === 'ephemeral';
912
+ }
913
+ function normalizeSource(value, fallback) {
914
+ const source = stringValue(value);
915
+ return /^[a-z][a-z0-9_:-]{0,60}$/.test(source) ? source : fallback;
916
+ }
917
+ function normalizeSourceType(value, fallback) {
918
+ if (value === 'user'
919
+ || value === 'model'
920
+ || value === 'system'
921
+ || value === 'tool'
922
+ || value === 'file'
923
+ || value === 'browser'
924
+ || value === 'external_agent') {
925
+ return value;
926
+ }
927
+ return fallback ?? 'model';
928
+ }
929
+ function normalizeScope(value, fallback) {
930
+ if (value === 'profile'
931
+ || value === 'workspace'
932
+ || value === 'project'
933
+ || value === 'session'
934
+ || value === 'task'
935
+ || value === 'global') {
936
+ return value;
937
+ }
938
+ return fallback;
939
+ }
940
+ function sourceTypeFromSource(source) {
941
+ if (source === 'user_direct' || source === 'manual')
942
+ return 'user';
943
+ if (source === 'system')
944
+ return 'system';
945
+ if (source.startsWith('tool'))
946
+ return 'tool';
947
+ if (source.startsWith('file'))
948
+ return 'file';
949
+ if (source.startsWith('browser'))
950
+ return 'browser';
951
+ if (source.startsWith('external_agent'))
952
+ return 'external_agent';
953
+ return 'model';
954
+ }
955
+ function defaultStability(kind) {
956
+ return kind === 'auto_short' ? 'session' : 'evolving';
957
+ }
958
+ function defaultPriority(kind, explicitDefault) {
959
+ return explicitDefault >= 0 && explicitDefault <= 10 ? explicitDefault : kind === 'auto_short' ? 5 : DEFAULT_PRIORITY;
960
+ }
961
+ function manualPriority(kind) {
962
+ if (kind === 'user')
963
+ return 1;
964
+ if (kind === 'preferences')
965
+ return 2;
966
+ return 3;
967
+ }
968
+ function manualStability(kind) {
969
+ return kind === 'auto_short' ? 'session' : 'stable';
970
+ }
971
+ function manualReason(kind) {
972
+ if (kind === 'user')
973
+ return 'Manual durable user memory command.';
974
+ if (kind === 'preferences')
975
+ return 'Manual durable preference memory command.';
976
+ return 'Manual short-term memory command.';
977
+ }
978
+ function looksTimeSensitive(text) {
979
+ const normalized = normalizeText(text);
980
+ if (!/\b(today|tomorrow|tonight|meeting|deadline|appointment|reminder|schedule)\b/.test(normalized))
981
+ return false;
982
+ return Boolean(/\b\d{1,2}(?::\d{2})?\s*(?:a\.?m\.?|p\.?m\.?|am|pm)\b/.test(normalized)
983
+ || /\b\d{4}-\d{2}-\d{2}\b/.test(normalized));
984
+ }
985
+ function looksResponsePreference(text) {
986
+ const normalized = normalizeText(text);
987
+ if (!/\b(prefer|prefers|preference|like|likes)\b/.test(normalized))
988
+ return false;
989
+ return Boolean(/\b(reply|replies|answer|answers|response|responses|conversation|tone|style)\b/.test(normalized)
990
+ || /\b(short|brief|concise|detailed|normal|casual|formal)\b/.test(normalized));
991
+ }
992
+ function looksIdentityNameFact(text) {
993
+ const normalized = normalizeText(text);
994
+ return Boolean(/\b(?:the\s+)?user(?:'s)?\s+name\s+is\b/.test(normalized)
995
+ || /\buser\s+is\s+named\b/.test(normalized)
996
+ || /^name\s*:/.test(normalized)
997
+ || /\bpreferred\s+name\b/.test(normalized)
998
+ || /\bcall\s+(?:the\s+)?user\b/.test(normalized));
999
+ }
1000
+ function isSimpleMemoryPrompt(prompt) {
1001
+ const normalized = normalizeText(prompt);
1002
+ if (!normalized || normalized.length > 80)
1003
+ return false;
1004
+ return [
1005
+ /^(?:hi|hello|hey|yo|sup|hiya|howdy)[!. ]*$/i,
1006
+ /^(?:thanks|thank you|thx|ty|ok|okay|k|cool|nice|great|got it|sounds good)[!. ]*$/i,
1007
+ /^(?:good morning|good afternoon|good evening|good night)[!. ]*$/i,
1008
+ /^(?:yes|no|yep|yeah|nope|sure|alright|all right)[!. ]*$/i,
1009
+ ].some(pattern => pattern.test(normalized));
1010
+ }
1011
+ function meetingDate(text) {
1012
+ const match = /\b\d{4}-\d{2}-\d{2}\b|\btomorrow\b|\btoday\b|\btonight\b/i.exec(text);
1013
+ return match ? match[0].toLowerCase() : '';
1014
+ }
1015
+ function serializedJsonlLength(entries) {
1016
+ return entries.reduce((sum, entry) => sum + JSON.stringify(entry).length + 1, 0);
1017
+ }
1018
+ function dedupeEntries(entries) {
1019
+ const deduped = new Map();
1020
+ for (const entry of entries) {
1021
+ const key = entryKey(entry);
1022
+ const existing = deduped.get(key);
1023
+ if (!existing || compareMemoryRank(entry, existing, new Set()) < 0)
1024
+ deduped.set(key, entry);
1025
+ }
1026
+ return [...deduped.values()];
1027
+ }
1028
+ function entryKey(entry) {
1029
+ return `${entry.kind}:${normalizeText(entry.text)}`;
1030
+ }
1031
+ function normalizeText(value) {
1032
+ return value.trim().toLowerCase().replace(/^\s*[-*]\s*/, '').replace(/\s+/g, ' ').replace(/[.;]+$/g, '');
1033
+ }
1034
+ function slotKey(value) {
1035
+ let key = value.trim().toLowerCase().replace(/colour/g, 'color');
1036
+ key = key.replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '').replace(/_+/g, '_');
1037
+ if (key.startsWith('fav_'))
1038
+ key = `favorite_${key.slice(4)}`;
1039
+ return key.slice(0, 40).replace(/^_+|_+$/g, '');
1040
+ }
1041
+ function tokens(value) {
1042
+ return new Set(value.toLowerCase().match(/[a-z0-9_]+/g) ?? []);
1043
+ }
1044
+ function intersects(a, b) {
1045
+ for (const item of a)
1046
+ if (b.has(item))
1047
+ return true;
1048
+ return false;
1049
+ }
1050
+ function isSubset(a, b) {
1051
+ for (const item of a)
1052
+ if (!b.has(item))
1053
+ return false;
1054
+ return true;
1055
+ }
1056
+ function intersectionSize(a, b) {
1057
+ let count = 0;
1058
+ for (const item of a)
1059
+ if (b.has(item))
1060
+ count += 1;
1061
+ return count;
1062
+ }
1063
+ function timestamp(value) {
1064
+ const parsed = Date.parse(value);
1065
+ return Number.isFinite(parsed) ? parsed / 1000 : 0;
1066
+ }
1067
+ function isExpired(entry, nowTs = Date.now() / 1000) {
1068
+ if (!entry.expires_at)
1069
+ return false;
1070
+ const expires = timestamp(entry.expires_at);
1071
+ return expires > 0 && expires <= nowTs;
1072
+ }
1073
+ function sortedUnique(values) {
1074
+ return [...new Set(values.filter(Boolean))].sort();
1075
+ }
1076
+ function clampInteger(value, fallback, low, high) {
1077
+ const number = typeof value === 'number' && Number.isFinite(value) ? Math.trunc(value) : fallback;
1078
+ return Math.max(low, Math.min(high, number));
1079
+ }
1080
+ function clampNumber(value, fallback, low, high) {
1081
+ const number = typeof value === 'number' && Number.isFinite(value) ? value : fallback;
1082
+ return Math.max(low, Math.min(high, number));
1083
+ }
1084
+ function finiteNumber(value) {
1085
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
1086
+ }
1087
+ function stringValue(value) {
1088
+ return typeof value === 'string' ? value.trim() : '';
1089
+ }
1090
+ function isRecord(value) {
1091
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
1092
+ }
1093
+ function utcNow() {
1094
+ return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
1095
+ }
1096
+ //# sourceMappingURL=MemoryStore.js.map