@zooique/memora 0.1.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 (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/dist/agent/agent.d.ts +343 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +893 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/assembler.d.ts +77 -0
  8. package/dist/agent/assembler.d.ts.map +1 -0
  9. package/dist/agent/assembler.js +115 -0
  10. package/dist/agent/assembler.js.map +1 -0
  11. package/dist/agent/builtinToolHandlers.d.ts +96 -0
  12. package/dist/agent/builtinToolHandlers.d.ts.map +1 -0
  13. package/dist/agent/builtinToolHandlers.js +388 -0
  14. package/dist/agent/builtinToolHandlers.js.map +1 -0
  15. package/dist/agent/builtinTools.d.ts +35 -0
  16. package/dist/agent/builtinTools.d.ts.map +1 -0
  17. package/dist/agent/builtinTools.js +75 -0
  18. package/dist/agent/builtinTools.js.map +1 -0
  19. package/dist/agent/constants.d.ts +67 -0
  20. package/dist/agent/constants.d.ts.map +1 -0
  21. package/dist/agent/constants.js +67 -0
  22. package/dist/agent/constants.js.map +1 -0
  23. package/dist/agent/contextManager.d.ts +130 -0
  24. package/dist/agent/contextManager.d.ts.map +1 -0
  25. package/dist/agent/contextManager.js +287 -0
  26. package/dist/agent/contextManager.js.map +1 -0
  27. package/dist/agent/loop.d.ts +288 -0
  28. package/dist/agent/loop.d.ts.map +1 -0
  29. package/dist/agent/loop.js +756 -0
  30. package/dist/agent/loop.js.map +1 -0
  31. package/dist/agent/managers/autoConfigRefiner.d.ts +39 -0
  32. package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -0
  33. package/dist/agent/managers/autoConfigRefiner.js +150 -0
  34. package/dist/agent/managers/autoConfigRefiner.js.map +1 -0
  35. package/dist/agent/managers/configManager.d.ts +114 -0
  36. package/dist/agent/managers/configManager.d.ts.map +1 -0
  37. package/dist/agent/managers/configManager.js +186 -0
  38. package/dist/agent/managers/configManager.js.map +1 -0
  39. package/dist/agent/managers/insightExtractor.d.ts +141 -0
  40. package/dist/agent/managers/insightExtractor.d.ts.map +1 -0
  41. package/dist/agent/managers/insightExtractor.js +420 -0
  42. package/dist/agent/managers/insightExtractor.js.map +1 -0
  43. package/dist/agent/managers/memoryAdvisor.d.ts +96 -0
  44. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -0
  45. package/dist/agent/managers/memoryAdvisor.js +198 -0
  46. package/dist/agent/managers/memoryAdvisor.js.map +1 -0
  47. package/dist/agent/managers/memoryInspector.d.ts +231 -0
  48. package/dist/agent/managers/memoryInspector.d.ts.map +1 -0
  49. package/dist/agent/managers/memoryInspector.js +327 -0
  50. package/dist/agent/managers/memoryInspector.js.map +1 -0
  51. package/dist/agent/managers/sessionManager.d.ts +89 -0
  52. package/dist/agent/managers/sessionManager.d.ts.map +1 -0
  53. package/dist/agent/managers/sessionManager.js +178 -0
  54. package/dist/agent/managers/sessionManager.js.map +1 -0
  55. package/dist/agent/managers/userFactExtractor.d.ts +25 -0
  56. package/dist/agent/managers/userFactExtractor.d.ts.map +1 -0
  57. package/dist/agent/managers/userFactExtractor.js +81 -0
  58. package/dist/agent/managers/userFactExtractor.js.map +1 -0
  59. package/dist/agent/managers/workProjection.d.ts +117 -0
  60. package/dist/agent/managers/workProjection.d.ts.map +1 -0
  61. package/dist/agent/managers/workProjection.js +290 -0
  62. package/dist/agent/managers/workProjection.js.map +1 -0
  63. package/dist/agent/messageHistory.d.ts +157 -0
  64. package/dist/agent/messageHistory.d.ts.map +1 -0
  65. package/dist/agent/messageHistory.js +288 -0
  66. package/dist/agent/messageHistory.js.map +1 -0
  67. package/dist/agent/toolExecutor.d.ts +137 -0
  68. package/dist/agent/toolExecutor.d.ts.map +1 -0
  69. package/dist/agent/toolExecutor.js +209 -0
  70. package/dist/agent/toolExecutor.js.map +1 -0
  71. package/dist/agent/tracer.d.ts +122 -0
  72. package/dist/agent/tracer.d.ts.map +1 -0
  73. package/dist/agent/tracer.js +64 -0
  74. package/dist/agent/tracer.js.map +1 -0
  75. package/dist/agent/types.d.ts +98 -0
  76. package/dist/agent/types.d.ts.map +1 -0
  77. package/dist/agent/types.js +19 -0
  78. package/dist/agent/types.js.map +1 -0
  79. package/dist/config/loader.d.ts +229 -0
  80. package/dist/config/loader.d.ts.map +1 -0
  81. package/dist/config/loader.js +194 -0
  82. package/dist/config/loader.js.map +1 -0
  83. package/dist/eval/evalTypes.d.ts +118 -0
  84. package/dist/eval/evalTypes.d.ts.map +1 -0
  85. package/dist/eval/evalTypes.js +102 -0
  86. package/dist/eval/evalTypes.js.map +1 -0
  87. package/dist/index.d.ts +61 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +44 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/llm/embedding.d.ts +62 -0
  92. package/dist/llm/embedding.d.ts.map +1 -0
  93. package/dist/llm/embedding.js +162 -0
  94. package/dist/llm/embedding.js.map +1 -0
  95. package/dist/llm/factory.d.ts +39 -0
  96. package/dist/llm/factory.d.ts.map +1 -0
  97. package/dist/llm/factory.js +108 -0
  98. package/dist/llm/factory.js.map +1 -0
  99. package/dist/llm/openaiCompatible.d.ts +63 -0
  100. package/dist/llm/openaiCompatible.d.ts.map +1 -0
  101. package/dist/llm/openaiCompatible.js +340 -0
  102. package/dist/llm/openaiCompatible.js.map +1 -0
  103. package/dist/llm/provider.d.ts +91 -0
  104. package/dist/llm/provider.d.ts.map +1 -0
  105. package/dist/llm/provider.js +14 -0
  106. package/dist/llm/provider.js.map +1 -0
  107. package/dist/llm/types.d.ts +25 -0
  108. package/dist/llm/types.d.ts.map +1 -0
  109. package/dist/llm/types.js +7 -0
  110. package/dist/llm/types.js.map +1 -0
  111. package/dist/logging/logger.d.ts +39 -0
  112. package/dist/logging/logger.d.ts.map +1 -0
  113. package/dist/logging/logger.js +279 -0
  114. package/dist/logging/logger.js.map +1 -0
  115. package/dist/logging/loggerInterface.d.ts +33 -0
  116. package/dist/logging/loggerInterface.d.ts.map +1 -0
  117. package/dist/logging/loggerInterface.js +2 -0
  118. package/dist/logging/loggerInterface.js.map +1 -0
  119. package/dist/memory/inMemoryRelationStore.d.ts +51 -0
  120. package/dist/memory/inMemoryRelationStore.d.ts.map +1 -0
  121. package/dist/memory/inMemoryRelationStore.js +65 -0
  122. package/dist/memory/inMemoryRelationStore.js.map +1 -0
  123. package/dist/memory/inMemoryStorage.d.ts +97 -0
  124. package/dist/memory/inMemoryStorage.d.ts.map +1 -0
  125. package/dist/memory/inMemoryStorage.js +177 -0
  126. package/dist/memory/inMemoryStorage.js.map +1 -0
  127. package/dist/memory/loader.d.ts +49 -0
  128. package/dist/memory/loader.d.ts.map +1 -0
  129. package/dist/memory/loader.js +93 -0
  130. package/dist/memory/loader.js.map +1 -0
  131. package/dist/memory/projectManager.d.ts +182 -0
  132. package/dist/memory/projectManager.d.ts.map +1 -0
  133. package/dist/memory/projectManager.js +441 -0
  134. package/dist/memory/projectManager.js.map +1 -0
  135. package/dist/memory/recall.d.ts +77 -0
  136. package/dist/memory/recall.d.ts.map +1 -0
  137. package/dist/memory/recall.js +147 -0
  138. package/dist/memory/recall.js.map +1 -0
  139. package/dist/memory/relationStore.d.ts +78 -0
  140. package/dist/memory/relationStore.d.ts.map +1 -0
  141. package/dist/memory/relationStore.js +2 -0
  142. package/dist/memory/relationStore.js.map +1 -0
  143. package/dist/memory/sessionStore.d.ts +84 -0
  144. package/dist/memory/sessionStore.d.ts.map +1 -0
  145. package/dist/memory/sessionStore.js +2 -0
  146. package/dist/memory/sessionStore.js.map +1 -0
  147. package/dist/memory/storageInterface.d.ts +107 -0
  148. package/dist/memory/storageInterface.d.ts.map +1 -0
  149. package/dist/memory/storageInterface.js +2 -0
  150. package/dist/memory/storageInterface.js.map +1 -0
  151. package/dist/memory/store.d.ts +50 -0
  152. package/dist/memory/store.d.ts.map +1 -0
  153. package/dist/memory/store.js +160 -0
  154. package/dist/memory/store.js.map +1 -0
  155. package/dist/memory/types.d.ts +189 -0
  156. package/dist/memory/types.d.ts.map +1 -0
  157. package/dist/memory/types.js +230 -0
  158. package/dist/memory/types.js.map +1 -0
  159. package/dist/memory/userProfile.d.ts +156 -0
  160. package/dist/memory/userProfile.d.ts.map +1 -0
  161. package/dist/memory/userProfile.js +315 -0
  162. package/dist/memory/userProfile.js.map +1 -0
  163. package/dist/memory/vectorStore.d.ts +75 -0
  164. package/dist/memory/vectorStore.d.ts.map +1 -0
  165. package/dist/memory/vectorStore.js +144 -0
  166. package/dist/memory/vectorStore.js.map +1 -0
  167. package/dist/persona/personaManager.d.ts +121 -0
  168. package/dist/persona/personaManager.d.ts.map +1 -0
  169. package/dist/persona/personaManager.js +349 -0
  170. package/dist/persona/personaManager.js.map +1 -0
  171. package/dist/persona/types.d.ts +32 -0
  172. package/dist/persona/types.d.ts.map +1 -0
  173. package/dist/persona/types.js +5 -0
  174. package/dist/persona/types.js.map +1 -0
  175. package/dist/security/pathGuard.d.ts +121 -0
  176. package/dist/security/pathGuard.d.ts.map +1 -0
  177. package/dist/security/pathGuard.js +276 -0
  178. package/dist/security/pathGuard.js.map +1 -0
  179. package/dist/skill/skillManager.d.ts +82 -0
  180. package/dist/skill/skillManager.d.ts.map +1 -0
  181. package/dist/skill/skillManager.js +198 -0
  182. package/dist/skill/skillManager.js.map +1 -0
  183. package/dist/skill/types.d.ts +28 -0
  184. package/dist/skill/types.d.ts.map +1 -0
  185. package/dist/skill/types.js +5 -0
  186. package/dist/skill/types.js.map +1 -0
  187. package/dist/utils/errors.d.ts +86 -0
  188. package/dist/utils/errors.d.ts.map +1 -0
  189. package/dist/utils/errors.js +143 -0
  190. package/dist/utils/errors.js.map +1 -0
  191. package/dist/utils/eventEmitter.d.ts +87 -0
  192. package/dist/utils/eventEmitter.d.ts.map +1 -0
  193. package/dist/utils/eventEmitter.js +79 -0
  194. package/dist/utils/eventEmitter.js.map +1 -0
  195. package/dist/utils/frontmatter.d.ts +24 -0
  196. package/dist/utils/frontmatter.d.ts.map +1 -0
  197. package/dist/utils/frontmatter.js +44 -0
  198. package/dist/utils/frontmatter.js.map +1 -0
  199. package/dist/utils/json.d.ts +20 -0
  200. package/dist/utils/json.d.ts.map +1 -0
  201. package/dist/utils/json.js +65 -0
  202. package/dist/utils/json.js.map +1 -0
  203. package/dist/utils/loggerHolder.d.ts +37 -0
  204. package/dist/utils/loggerHolder.d.ts.map +1 -0
  205. package/dist/utils/loggerHolder.js +49 -0
  206. package/dist/utils/loggerHolder.js.map +1 -0
  207. package/dist/utils/math.d.ts +5 -0
  208. package/dist/utils/math.d.ts.map +1 -0
  209. package/dist/utils/math.js +19 -0
  210. package/dist/utils/math.js.map +1 -0
  211. package/dist/utils/path.d.ts +28 -0
  212. package/dist/utils/path.d.ts.map +1 -0
  213. package/dist/utils/path.js +33 -0
  214. package/dist/utils/path.js.map +1 -0
  215. package/dist/utils/safeTimer.d.ts +26 -0
  216. package/dist/utils/safeTimer.d.ts.map +1 -0
  217. package/dist/utils/safeTimer.js +49 -0
  218. package/dist/utils/safeTimer.js.map +1 -0
  219. package/dist/utils/scanner.d.ts +54 -0
  220. package/dist/utils/scanner.d.ts.map +1 -0
  221. package/dist/utils/scanner.js +115 -0
  222. package/dist/utils/scanner.js.map +1 -0
  223. package/dist/utils/segmenter.d.ts +30 -0
  224. package/dist/utils/segmenter.d.ts.map +1 -0
  225. package/dist/utils/segmenter.js +80 -0
  226. package/dist/utils/segmenter.js.map +1 -0
  227. package/dist/utils/strings.d.ts +18 -0
  228. package/dist/utils/strings.d.ts.map +1 -0
  229. package/dist/utils/strings.js +25 -0
  230. package/dist/utils/strings.js.map +1 -0
  231. package/dist/utils/time.d.ts +23 -0
  232. package/dist/utils/time.d.ts.map +1 -0
  233. package/dist/utils/time.js +31 -0
  234. package/dist/utils/time.js.map +1 -0
  235. package/dist/utils/toError.d.ts +13 -0
  236. package/dist/utils/toError.d.ts.map +1 -0
  237. package/dist/utils/toError.js +22 -0
  238. package/dist/utils/toError.js.map +1 -0
  239. package/package.json +73 -0
@@ -0,0 +1,177 @@
1
+ import { validateSource } from '../memory/types.js';
2
+ import { segmentText } from '../utils/segmenter.js';
3
+ import { logger } from '../logging/logger.js';
4
+ import { applyDecayToMemory } from '../memory/recall.js';
5
+ /**
6
+ * 内存存储实现
7
+ *
8
+ * 使用 Map 存储记忆,核心操作 O(1)~O(log n)。
9
+ * P2-2 优化:维护 source→count 增量缓存,stats()/sourceHealth() 无需全量遍历。
10
+ */
11
+ export class InMemoryStorage {
12
+ /** 记忆存储(id → Memory) */
13
+ memories = new Map();
14
+ /** P2-2 source→count 增量缓存(upsert/delete 时维护,getAllSources 时直接读取) */
15
+ sourceCountCache = new Map();
16
+ /**
17
+ * 插入或更新记忆
18
+ *
19
+ * 自动校验 source 字段,对疑似 typo 发出警告日志。
20
+ * P2-2 增量维护 sourceCountCache:更新时旧 source 减 1、新 source 加 1。
21
+ */
22
+ upsert(memory) {
23
+ const result = validateSource(memory.source);
24
+ if (result.severity === 'block') {
25
+ throw new Error(`source 校验失败(拒绝写入):${result.warning}`);
26
+ }
27
+ if (result.severity === 'warn' && result.warning) {
28
+ logger.warn({ id: memory.id, source: memory.source, warning: result.warning }, 'source 校验警告');
29
+ }
30
+ // P2-2 增量维护 source 缓存:若为更新(id 已存在),先减旧 source 计数
31
+ const existing = this.memories.get(memory.id);
32
+ if (existing && existing.source !== memory.source) {
33
+ this.decrementSourceCount(existing.source);
34
+ }
35
+ this.memories.set(memory.id, { ...memory });
36
+ // P2-2 增量维护 source 缓存:新 source 加 1
37
+ this.incrementSourceCount(memory.source);
38
+ }
39
+ /**
40
+ * 删除记忆
41
+ *
42
+ * P2-2 增量维护 sourceCountCache:删除时对应 source 减 1。
43
+ */
44
+ delete(id) {
45
+ const existing = this.memories.get(id);
46
+ if (existing) {
47
+ this.decrementSourceCount(existing.source);
48
+ }
49
+ this.memories.delete(id);
50
+ }
51
+ /**
52
+ * 按 ID 获取单条记忆
53
+ *
54
+ * 返回浅拷贝,避免调用方修改污染存储内部对象(接口契约:读取隔离)
55
+ */
56
+ getById(id) {
57
+ const m = this.memories.get(id);
58
+ return m ? { ...m } : null;
59
+ }
60
+ /**
61
+ * 按来源标签获取记忆
62
+ *
63
+ * 返回浅拷贝数组,避免调用方修改污染存储内部对象。
64
+ *
65
+ * @param source - 来源标签(如 'persona'、'rule'、'insight')
66
+ * @returns 该来源的所有记忆(副本),按 score 降序排列
67
+ */
68
+ getBySource(source) {
69
+ return Array.from(this.memories.values())
70
+ .filter((m) => m.source === source)
71
+ .sort((a, b) => b.score - a.score)
72
+ .map((m) => ({ ...m }));
73
+ }
74
+ /**
75
+ * 文本搜索(内存版)
76
+ *
77
+ * 使用 segmentText() 规范分词,与 SqliteStorage 行为一致。
78
+ * 搜索 content 和 name 字段,按 score 降序排列。
79
+ *
80
+ * @param query - 搜索查询文本
81
+ * @param limit - 返回数量上限(默认 10)
82
+ * @returns 匹配的记忆列表
83
+ */
84
+ search(query, limit = 10) {
85
+ // 空查询:按 score 降序返回(浅拷贝,读取隔离)
86
+ if (!query.trim()) {
87
+ return Array.from(this.memories.values())
88
+ .sort((a, b) => b.score - a.score)
89
+ .slice(0, limit)
90
+ .map((m) => ({ ...m }));
91
+ }
92
+ // 规范分词(与 recall.ts extractKeywords 共用 segmentText)
93
+ const tokens = segmentText(query).map((t) => t.toLowerCase());
94
+ // 若分词后无有效 token,降级为按 score 返回
95
+ if (tokens.length === 0) {
96
+ return Array.from(this.memories.values())
97
+ .sort((a, b) => b.score - a.score)
98
+ .slice(0, limit)
99
+ .map((m) => ({ ...m }));
100
+ }
101
+ const results = Array.from(this.memories.values()).filter((m) => {
102
+ const text = `${m.content} ${m.name}`.toLowerCase();
103
+ // 任一 token 命中即可
104
+ return tokens.some((t) => text.includes(t));
105
+ });
106
+ // 按 score 降序排序
107
+ results.sort((a, b) => b.score - a.score);
108
+ // 返回浅拷贝,避免调用方修改污染存储内部对象
109
+ return results.slice(0, limit).map((m) => ({ ...m }));
110
+ }
111
+ /**
112
+ * 统计记忆总数
113
+ */
114
+ count() {
115
+ return this.memories.size;
116
+ }
117
+ /**
118
+ * 按来源标签统计记忆数量
119
+ *
120
+ * P2-2 优化:直接读取 sourceCountCache,O(1) 复杂度(与 getAllSources 一致)
121
+ * 原实现 O(n) 遍历所有记忆,与增量缓存设计不一致
122
+ */
123
+ countBySource(source) {
124
+ return this.sourceCountCache.get(source) ?? 0;
125
+ }
126
+ /**
127
+ * 衰减指定来源的记忆 score
128
+ *
129
+ * 遍历所有匹配 source 的记忆,按时间衰减。
130
+ * 生产环境宿主(SqliteStorage)应重写为 SQL UPDATE 批量操作。
131
+ */
132
+ decayScores(sources, now) {
133
+ let count = 0;
134
+ for (const m of this.memories.values()) {
135
+ if (!sources.includes(m.source))
136
+ continue;
137
+ if (applyDecayToMemory(m, now)) {
138
+ count++;
139
+ }
140
+ }
141
+ return count;
142
+ }
143
+ /**
144
+ * 获取所有 source 标签及其记忆数量
145
+ *
146
+ * P2-2 优化:直接读取增量维护的 sourceCountCache,O(1) 复杂度。
147
+ */
148
+ getAllSources() {
149
+ return new Map(this.sourceCountCache);
150
+ }
151
+ /**
152
+ * 关闭(内存实现无需关闭)
153
+ */
154
+ close() {
155
+ // 内存实现无需关闭,清空数据即可
156
+ this.memories.clear();
157
+ this.sourceCountCache.clear();
158
+ }
159
+ // ─── P2-2 source 缓存辅助方法 ─────────────────────────────
160
+ /** source 计数 +1 */
161
+ incrementSourceCount(source) {
162
+ this.sourceCountCache.set(source, (this.sourceCountCache.get(source) ?? 0) + 1);
163
+ }
164
+ /** source 计数 -1(减至 0 时移除键) */
165
+ decrementSourceCount(source) {
166
+ const current = this.sourceCountCache.get(source);
167
+ if (current === undefined)
168
+ return;
169
+ if (current <= 1) {
170
+ this.sourceCountCache.delete(source);
171
+ }
172
+ else {
173
+ this.sourceCountCache.set(source, current - 1);
174
+ }
175
+ }
176
+ }
177
+ //# sourceMappingURL=inMemoryStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryStorage.js","sourceRoot":"","sources":["../../src/memory/inMemoryStorage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 记忆加载器
3
+ *
4
+ * 职责:把文件系统的记忆(personas/rules/skills)加载到 SQLite 索引
5
+ * 启动时:扫描文件 → 写入索引 → 按 source 召回必召记忆
6
+ *
7
+ * 这是"万物皆记忆"哲学的代码体现——所有记忆共享同一条加载管线
8
+ */
9
+ import type { FileStore } from '../memory/store.js';
10
+ import type { IMemoryStorage } from '../memory/storageInterface.js';
11
+ import { type Memory } from '../memory/types.js';
12
+ export interface LoadResult {
13
+ /** 实际加载到索引的记忆数量 */
14
+ loaded: number;
15
+ /** 跳过的记忆(解析失败等) */
16
+ skipped: number;
17
+ /** 加载失败的详情 */
18
+ errors: Array<{
19
+ file: string;
20
+ error: string;
21
+ }>;
22
+ }
23
+ export declare class MemoryLoader {
24
+ private readonly fileStore;
25
+ private readonly index;
26
+ constructor(fileStore: FileStore, index: IMemoryStorage);
27
+ /**
28
+ * 扫描所有"配置类"记忆文件(persona/rule/skill)
29
+ * 写入 SQLite 索引
30
+ *
31
+ * @returns 加载结果统计
32
+ */
33
+ loadAllToIndex(): Promise<LoadResult>;
34
+ /**
35
+ * 启动时的完整引导流程
36
+ * 1. 扫描配置文件 → 写入索引
37
+ * 2. 从索引按 source 召回必召记忆(rule + skill)
38
+ *
39
+ * 注:persona 记忆由 PersonaManager 单独处理,
40
+ * bootstrap 中自动跳过 persona(避免与 systemPromptPrefix 中的角色 prompt 重复)。
41
+ *
42
+ * @returns 启动时必召的所有记忆(用于初始化 Agent Loop 的 system prompt)
43
+ */
44
+ bootstrap(): Promise<{
45
+ memories: Memory[];
46
+ loadResult: LoadResult;
47
+ }>;
48
+ }
49
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/memory/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA6B/D,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,cAAc;IAGxC;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC;IAgC3C;;;;;;;;;OASG;IACG,SAAS,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC;CAW3E"}
@@ -0,0 +1,93 @@
1
+ import { SOURCE_LABELS } from '../memory/types.js';
2
+ import { toError } from '../utils/errors.js';
3
+ /**
4
+ * 启动时全量扫描的 source 列表
5
+ * - insight/profile/work-projection:运行时产生,不由 FileStore 管理
6
+ * - tool:由 registerTool() 注册为 tool_call,不再重复注入 system prompt
7
+ * - guardrail:由 AgentLoop 运行时读取,不注入 system prompt
8
+ */
9
+ const STARTUP_SCAN_SOURCES = [
10
+ SOURCE_LABELS.PERSONA,
11
+ SOURCE_LABELS.RULE,
12
+ SOURCE_LABELS.SKILL,
13
+ SOURCE_LABELS.GUARDRAIL,
14
+ ];
15
+ /**
16
+ * 判断内容是否为空壳模板(仅含标题和 blockquote 占位说明)
17
+ * 新建项目时的空壳规则模板属于此类
18
+ *
19
+ * 判断逻辑:过滤掉标题行和空行后,剩余内容全部是 blockquote 行
20
+ */
21
+ function isPlaceholderContent(memory) {
22
+ const trimmed = memory.content.trim();
23
+ if (trimmed.length > 200)
24
+ return false;
25
+ const lines = trimmed.split('\n').filter(l => l.trim() && !l.trim().startsWith('#'));
26
+ return lines.length > 0 && lines.every(l => l.trim().startsWith('>'));
27
+ }
28
+ export class MemoryLoader {
29
+ fileStore;
30
+ index;
31
+ constructor(fileStore, index) {
32
+ this.fileStore = fileStore;
33
+ this.index = index;
34
+ }
35
+ /**
36
+ * 扫描所有"配置类"记忆文件(persona/rule/skill)
37
+ * 写入 SQLite 索引
38
+ *
39
+ * @returns 加载结果统计
40
+ */
41
+ async loadAllToIndex() {
42
+ const result = { loaded: 0, skipped: 0, errors: [] };
43
+ for (const source of STARTUP_SCAN_SOURCES) {
44
+ const names = await this.fileStore.list(source);
45
+ for (const name of names) {
46
+ try {
47
+ const memory = await this.fileStore.read(source, name);
48
+ if (!memory) {
49
+ result.skipped++;
50
+ continue;
51
+ }
52
+ // 跳过空壳模板(新建项目时的占位文件,无实质规则内容)
53
+ if (isPlaceholderContent(memory)) {
54
+ result.skipped++;
55
+ continue;
56
+ }
57
+ this.index.upsert(memory);
58
+ result.loaded++;
59
+ }
60
+ catch (err) {
61
+ result.skipped++;
62
+ result.errors.push({
63
+ file: `${source}/${name}`,
64
+ error: toError(err).message,
65
+ });
66
+ }
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+ /**
72
+ * 启动时的完整引导流程
73
+ * 1. 扫描配置文件 → 写入索引
74
+ * 2. 从索引按 source 召回必召记忆(rule + skill)
75
+ *
76
+ * 注:persona 记忆由 PersonaManager 单独处理,
77
+ * bootstrap 中自动跳过 persona(避免与 systemPromptPrefix 中的角色 prompt 重复)。
78
+ *
79
+ * @returns 启动时必召的所有记忆(用于初始化 Agent Loop 的 system prompt)
80
+ */
81
+ async bootstrap() {
82
+ const loadResult = await this.loadAllToIndex();
83
+ // 按 source 获取 rule 和 skill 记忆(跳过 persona,由 PersonaManager 单独管理)
84
+ const rules = this.index.getBySource(SOURCE_LABELS.RULE);
85
+ const skills = this.index.getBySource(SOURCE_LABELS.SKILL);
86
+ const memories = [...rules, ...skills];
87
+ return {
88
+ memories,
89
+ loadResult,
90
+ };
91
+ }
92
+ }
93
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/memory/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ import { FileStore } from '../memory/store.js';
2
+ import type { IMemoryStorage } from '../memory/storageInterface.js';
3
+ import type { LoadResult } from '../memory/loader.js';
4
+ import type { SecurityGuard } from '../security/pathGuard.js';
5
+ import { type Memory } from '../memory/types.js';
6
+ /**
7
+ * 项目上下文:打开一个项目后产出的一组组件
8
+ * 与 DomainContext 类似,但增加了项目级别的信息
9
+ */
10
+ export interface ProjectContext {
11
+ /** 项目根目录的绝对路径 */
12
+ projectPath: string;
13
+ /** 项目名称(从注册表读取,或取目录名) */
14
+ projectName: string;
15
+ /** .memora/ 目录的绝对路径 */
16
+ memoraDir: string;
17
+ /** Agent 级 memora.db 路径(全局共享,非项目级) */
18
+ dbPath: string;
19
+ /** 文件存储 */
20
+ fileStore: FileStore;
21
+ /** SQLite 索引(通过 IMemoryStorage 接口访问) */
22
+ index: IMemoryStorage;
23
+ /** 安全守卫(A-004: 可空,由 Agent 层注入工厂函数创建) */
24
+ security: SecurityGuard | null;
25
+ /** 启动时加载的必召记忆 */
26
+ bootstrapMemories: Memory[];
27
+ /** 加载结果 */
28
+ loadResult: LoadResult;
29
+ }
30
+ /**
31
+ * 项目注册表条目
32
+ */
33
+ export interface ProjectEntry {
34
+ /** 项目根目录的绝对路径 */
35
+ path: string;
36
+ /** 项目名称(用户自定义或目录名) */
37
+ name: string;
38
+ /** 最后打开时间 */
39
+ lastOpened: string;
40
+ }
41
+ /**
42
+ * ProjectManager 构造选项
43
+ */
44
+ export interface ProjectManagerOptions {
45
+ /** Agent 级数据目录(memora.db 所在目录) */
46
+ dataDir: string;
47
+ /** 外部注入的存储实例(可选,不传则内部创建 InMemoryStorage 兜底) */
48
+ storage?: IMemoryStorage;
49
+ /** 注册表目录(可选,默认与 dataDir 相同) */
50
+ registryDir?: string;
51
+ /**
52
+ * A-004: SecurityGuard 工厂函数(由 Agent 层注入,解除 memory→security 反向依赖)
53
+ *
54
+ * 在项目切换时调用,传入项目路径、.memora/ 目录、Agent 级配置目录和数据目录,
55
+ * 返回一个配置好的 SecurityGuard 实例。
56
+ * 不提供时 ProjectContext.security 为 null(宿主需自行处理安全校验)。
57
+ */
58
+ createSecurityGuard?: (projectPath: string, memoraDir: string, configDir?: string, agentDataDir?: string) => SecurityGuard;
59
+ }
60
+ /**
61
+ * 项目管理器
62
+ *
63
+ * 管理多项目的生命周期:
64
+ * 1. 初始化当前项目(加锁 + 加载两层配置)
65
+ * 2. /project <name> 切换到新项目(解锁旧项目 + 加锁新项目)
66
+ * 3. 退出时清理锁文件
67
+ */
68
+ export declare class ProjectManager {
69
+ /** 项目注册表路径 */
70
+ private readonly registryPath;
71
+ /** Agent 级数据目录(memora.db 所在目录) */
72
+ private readonly agentDataDir;
73
+ /** Agent 级存储实例(全局共享,不随项目切换重建) */
74
+ private agentIndex;
75
+ /** 当前打开的项目路径 */
76
+ private currentProjectPath;
77
+ /** 当前持有的锁文件路径 */
78
+ private currentLockPath;
79
+ /** 外部注入的存储实例(可选,不传则内部创建 InMemoryStorage 兜底) */
80
+ private externalStorage;
81
+ /** A-004: SecurityGuard 工厂函数(由 Agent 层注入) */
82
+ private readonly createSecurityGuard?;
83
+ constructor(options: ProjectManagerOptions);
84
+ /**
85
+ * 确保 Agent 级资源已初始化(存储实例)
86
+ * 存储实例在整个 Agent 生命周期内共享,不随项目切换重建
87
+ *
88
+ * 如果构造时注入了外部存储实例,直接使用;
89
+ * 否则内部创建 InMemoryStorage(非持久化兜底,仅开发/测试用)。
90
+ */
91
+ private ensureAgentResources;
92
+ /**
93
+ * 初始化指定项目
94
+ *
95
+ * 两层记忆加载:
96
+ * 1) 项目级:扫描 projectPath/.memora/rules/ + skills/
97
+ * 2) Agent 级:扫描 configDir 下的所有配置(rules/skills/personas/tools)
98
+ *
99
+ * 全局规则不再由内核硬编码路径,宿主可通过 configDir 统一管理。
100
+ *
101
+ * memora.db 是 Agent 级共享资源,不随项目切换重建。
102
+ *
103
+ * @param projectPath 项目根目录
104
+ * @param projectName 项目名称(可选,默认取目录名)
105
+ * @param configDir Agent 级配置目录(personas/rules/skills/tools)
106
+ */
107
+ initProject(projectPath: string, projectName?: string, configDir?: string): Promise<ProjectContext>;
108
+ /**
109
+ * 关闭当前项目
110
+ * 释放锁文件,但不关闭 Agent 级数据库(memora.db 是共享的)
111
+ */
112
+ closeProject(): Promise<void>;
113
+ /**
114
+ * 完全关闭:释放项目锁 + 关闭 Agent 级数据库
115
+ * 应在 Agent 整体关闭时调用(而非项目切换时)
116
+ */
117
+ shutdown(): Promise<void>;
118
+ /**
119
+ * 列出已注册的项目(IX-02:统一为 getter 风格,与 persona/skill 一致)
120
+ */
121
+ get list(): ProjectEntry[];
122
+ /**
123
+ * 列出已注册的项目
124
+ * @deprecated 请使用 `projectManager.list` getter 代替
125
+ */
126
+ listProjects(): ProjectEntry[];
127
+ /**
128
+ * 注册项目到注册表
129
+ */
130
+ registerProject(projectPath: string, name: string): void;
131
+ /**
132
+ * 从注册表移除项目
133
+ */
134
+ unregisterProject(projectPath: string): void;
135
+ /**
136
+ * 获取当前项目路径
137
+ */
138
+ get currentProject(): string | null;
139
+ /**
140
+ * 获取锁文件
141
+ * 如果锁文件存在且进程存活,发出警告但不阻止
142
+ * 如果锁文件存在但进程已死,清理残留锁
143
+ */
144
+ private acquireLock;
145
+ /**
146
+ * 释放锁文件
147
+ */
148
+ private releaseLock;
149
+ /**
150
+ * 安全删除文件(忽略不存在的错误)
151
+ */
152
+ private safeUnlink;
153
+ /**
154
+ * 检查进程是否存活
155
+ * Windows: tasklist /FI "PID eq <pid>"
156
+ * POSIX: kill(pid, 0)
157
+ */
158
+ private isProcessAlive;
159
+ /**
160
+ * 解析项目的 .memora/ 目录路径
161
+ * 每个项目有独立的 .memora/ 目录(在项目根目录下)
162
+ * 这与 config.memory.dataDir(用户级默认目录)不同
163
+ */
164
+ private resolveMemoraDir;
165
+ /**
166
+ * 从项目路径推断项目名称
167
+ * 取路径最后一段目录名
168
+ */
169
+ private inferProjectName;
170
+ /**
171
+ * 读取项目注册表
172
+ *
173
+ * 同步读取:list getter 契约要求同步返回,注册表操作低频,同步 I/O 影响可控
174
+ * 损坏时返回空数组并记录警告日志,避免静默吞错掩盖磁盘故障
175
+ */
176
+ private readRegistry;
177
+ /**
178
+ * 写入项目注册表
179
+ */
180
+ private writeRegistry;
181
+ }
182
+ //# sourceMappingURL=projectManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectManager.d.ts","sourceRoot":"","sources":["../../src/memory/projectManager.ts"],"names":[],"mappings":"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"}