@zooique/memora 0.1.0 → 0.2.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 (190) hide show
  1. package/dist/agent/agent.d.ts +155 -23
  2. package/dist/agent/agent.d.ts.map +1 -1
  3. package/dist/agent/agent.js +386 -124
  4. package/dist/agent/agent.js.map +1 -1
  5. package/dist/agent/assembler.d.ts +8 -2
  6. package/dist/agent/assembler.d.ts.map +1 -1
  7. package/dist/agent/assembler.js +17 -6
  8. package/dist/agent/assembler.js.map +1 -1
  9. package/dist/agent/builtinToolHandlers.d.ts +1 -1
  10. package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
  11. package/dist/agent/builtinToolHandlers.js +5 -3
  12. package/dist/agent/builtinToolHandlers.js.map +1 -1
  13. package/dist/agent/builtinTools.d.ts +1 -1
  14. package/dist/agent/builtinTools.js +2 -2
  15. package/dist/agent/builtinTools.js.map +1 -1
  16. package/dist/agent/constants.d.ts +27 -6
  17. package/dist/agent/constants.d.ts.map +1 -1
  18. package/dist/agent/constants.js +27 -6
  19. package/dist/agent/constants.js.map +1 -1
  20. package/dist/agent/contextManager.d.ts +35 -9
  21. package/dist/agent/contextManager.d.ts.map +1 -1
  22. package/dist/agent/contextManager.js +138 -25
  23. package/dist/agent/contextManager.js.map +1 -1
  24. package/dist/agent/loop.d.ts +41 -11
  25. package/dist/agent/loop.d.ts.map +1 -1
  26. package/dist/agent/loop.js +143 -61
  27. package/dist/agent/loop.js.map +1 -1
  28. package/dist/agent/managers/archiveCoordinator.d.ts +100 -0
  29. package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -0
  30. package/dist/agent/managers/archiveCoordinator.js +127 -0
  31. package/dist/agent/managers/archiveCoordinator.js.map +1 -0
  32. package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -1
  33. package/dist/agent/managers/autoConfigRefiner.js +1 -1
  34. package/dist/agent/managers/autoConfigRefiner.js.map +1 -1
  35. package/dist/agent/managers/configManager.d.ts +13 -2
  36. package/dist/agent/managers/configManager.d.ts.map +1 -1
  37. package/dist/agent/managers/configManager.js +13 -5
  38. package/dist/agent/managers/configManager.js.map +1 -1
  39. package/dist/agent/managers/insightExtractor.d.ts +36 -3
  40. package/dist/agent/managers/insightExtractor.d.ts.map +1 -1
  41. package/dist/agent/managers/insightExtractor.js +48 -11
  42. package/dist/agent/managers/insightExtractor.js.map +1 -1
  43. package/dist/agent/managers/memoryAdvisor.d.ts +4 -2
  44. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
  45. package/dist/agent/managers/memoryAdvisor.js +6 -4
  46. package/dist/agent/managers/memoryAdvisor.js.map +1 -1
  47. package/dist/agent/managers/memoryDecayScheduler.d.ts +113 -0
  48. package/dist/agent/managers/memoryDecayScheduler.d.ts.map +1 -0
  49. package/dist/agent/managers/memoryDecayScheduler.js +134 -0
  50. package/dist/agent/managers/memoryDecayScheduler.js.map +1 -0
  51. package/dist/agent/managers/memoryInspector.d.ts +70 -10
  52. package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
  53. package/dist/agent/managers/memoryInspector.js +97 -23
  54. package/dist/agent/managers/memoryInspector.js.map +1 -1
  55. package/dist/agent/managers/sessionArchiver.d.ts +77 -0
  56. package/dist/agent/managers/sessionArchiver.d.ts.map +1 -0
  57. package/dist/agent/managers/sessionArchiver.js +175 -0
  58. package/dist/agent/managers/sessionArchiver.js.map +1 -0
  59. package/dist/agent/managers/sessionManager.d.ts +10 -0
  60. package/dist/agent/managers/sessionManager.d.ts.map +1 -1
  61. package/dist/agent/managers/sessionManager.js +26 -5
  62. package/dist/agent/managers/sessionManager.js.map +1 -1
  63. package/dist/agent/managers/workProjection.d.ts +1 -1
  64. package/dist/agent/managers/workProjection.d.ts.map +1 -1
  65. package/dist/agent/managers/workProjection.js +13 -10
  66. package/dist/agent/managers/workProjection.js.map +1 -1
  67. package/dist/agent/messageHistory.d.ts +1 -22
  68. package/dist/agent/messageHistory.d.ts.map +1 -1
  69. package/dist/agent/messageHistory.js +3 -19
  70. package/dist/agent/messageHistory.js.map +1 -1
  71. package/dist/agent/toolExecutor.d.ts +5 -18
  72. package/dist/agent/toolExecutor.d.ts.map +1 -1
  73. package/dist/agent/toolExecutor.js +7 -7
  74. package/dist/agent/toolExecutor.js.map +1 -1
  75. package/dist/agent/tracer.d.ts +8 -1
  76. package/dist/agent/tracer.d.ts.map +1 -1
  77. package/dist/agent/tracer.js +8 -1
  78. package/dist/agent/tracer.js.map +1 -1
  79. package/dist/agent/types.d.ts +29 -0
  80. package/dist/agent/types.d.ts.map +1 -1
  81. package/dist/agent/{managers/userFactExtractor.d.ts → userFactExtractor.d.ts} +2 -2
  82. package/dist/agent/userFactExtractor.d.ts.map +1 -0
  83. package/dist/agent/userFactExtractor.js.map +1 -0
  84. package/dist/config/loader.d.ts +4 -4
  85. package/dist/config/loader.d.ts.map +1 -1
  86. package/dist/config/loader.js +11 -2
  87. package/dist/config/loader.js.map +1 -1
  88. package/dist/eval/evalTypes.js +1 -1
  89. package/dist/eval/evalTypes.js.map +1 -1
  90. package/dist/index.d.ts +5 -2
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +2 -1
  93. package/dist/index.js.map +1 -1
  94. package/dist/llm/embedding.d.ts.map +1 -1
  95. package/dist/llm/embedding.js +8 -6
  96. package/dist/llm/embedding.js.map +1 -1
  97. package/dist/llm/factory.d.ts.map +1 -1
  98. package/dist/llm/factory.js +2 -1
  99. package/dist/llm/factory.js.map +1 -1
  100. package/dist/llm/openaiCompatible.d.ts +9 -0
  101. package/dist/llm/openaiCompatible.d.ts.map +1 -1
  102. package/dist/llm/openaiCompatible.js +77 -33
  103. package/dist/llm/openaiCompatible.js.map +1 -1
  104. package/dist/llm/provider.d.ts +17 -3
  105. package/dist/llm/provider.d.ts.map +1 -1
  106. package/dist/llm/provider.js +6 -2
  107. package/dist/llm/provider.js.map +1 -1
  108. package/dist/logging/logger.d.ts.map +1 -1
  109. package/dist/logging/logger.js +25 -9
  110. package/dist/logging/logger.js.map +1 -1
  111. package/dist/memory/hybridMerge.d.ts +54 -0
  112. package/dist/memory/hybridMerge.d.ts.map +1 -0
  113. package/dist/memory/hybridMerge.js +36 -0
  114. package/dist/memory/hybridMerge.js.map +1 -0
  115. package/dist/memory/inMemoryStorage.d.ts +90 -15
  116. package/dist/memory/inMemoryStorage.d.ts.map +1 -1
  117. package/dist/memory/inMemoryStorage.js +179 -28
  118. package/dist/memory/inMemoryStorage.js.map +1 -1
  119. package/dist/memory/loader.js +1 -1
  120. package/dist/memory/loader.js.map +1 -1
  121. package/dist/memory/projectManager.d.ts +34 -5
  122. package/dist/memory/projectManager.d.ts.map +1 -1
  123. package/dist/memory/projectManager.js +98 -62
  124. package/dist/memory/projectManager.js.map +1 -1
  125. package/dist/memory/recall.d.ts +7 -18
  126. package/dist/memory/recall.d.ts.map +1 -1
  127. package/dist/memory/recall.js +14 -19
  128. package/dist/memory/recall.js.map +1 -1
  129. package/dist/memory/storageInterface.d.ts +81 -14
  130. package/dist/memory/storageInterface.d.ts.map +1 -1
  131. package/dist/memory/store.js +1 -1
  132. package/dist/memory/store.js.map +1 -1
  133. package/dist/memory/types.d.ts +7 -1
  134. package/dist/memory/types.d.ts.map +1 -1
  135. package/dist/memory/types.js +5 -1
  136. package/dist/memory/types.js.map +1 -1
  137. package/dist/memory/userProfile.d.ts +6 -6
  138. package/dist/memory/userProfile.d.ts.map +1 -1
  139. package/dist/memory/userProfile.js +20 -15
  140. package/dist/memory/userProfile.js.map +1 -1
  141. package/dist/memory/vectorStore.d.ts +35 -0
  142. package/dist/memory/vectorStore.d.ts.map +1 -1
  143. package/dist/memory/vectorStore.js +111 -2
  144. package/dist/memory/vectorStore.js.map +1 -1
  145. package/dist/persona/personaManager.d.ts +17 -4
  146. package/dist/persona/personaManager.d.ts.map +1 -1
  147. package/dist/persona/personaManager.js +44 -12
  148. package/dist/persona/personaManager.js.map +1 -1
  149. package/dist/security/pathGuard.d.ts +29 -7
  150. package/dist/security/pathGuard.d.ts.map +1 -1
  151. package/dist/security/pathGuard.js +148 -81
  152. package/dist/security/pathGuard.js.map +1 -1
  153. package/dist/skill/skillManager.d.ts +15 -0
  154. package/dist/skill/skillManager.d.ts.map +1 -1
  155. package/dist/skill/skillManager.js +25 -3
  156. package/dist/skill/skillManager.js.map +1 -1
  157. package/dist/skill/types.d.ts +7 -1
  158. package/dist/skill/types.d.ts.map +1 -1
  159. package/dist/utils/errors.d.ts +26 -7
  160. package/dist/utils/errors.d.ts.map +1 -1
  161. package/dist/utils/errors.js +10 -18
  162. package/dist/utils/errors.js.map +1 -1
  163. package/dist/utils/eventEmitter.d.ts +9 -2
  164. package/dist/utils/eventEmitter.d.ts.map +1 -1
  165. package/dist/utils/eventEmitter.js +1 -1
  166. package/dist/utils/eventEmitter.js.map +1 -1
  167. package/dist/utils/frontmatter.d.ts +8 -1
  168. package/dist/utils/frontmatter.d.ts.map +1 -1
  169. package/dist/utils/frontmatter.js +14 -3
  170. package/dist/utils/frontmatter.js.map +1 -1
  171. package/dist/utils/path.d.ts +5 -1
  172. package/dist/utils/path.d.ts.map +1 -1
  173. package/dist/utils/path.js +5 -1
  174. package/dist/utils/path.js.map +1 -1
  175. package/dist/utils/safeTimer.d.ts +19 -0
  176. package/dist/utils/safeTimer.d.ts.map +1 -1
  177. package/dist/utils/safeTimer.js +27 -0
  178. package/dist/utils/safeTimer.js.map +1 -1
  179. package/dist/utils/segmenter.d.ts +0 -12
  180. package/dist/utils/segmenter.d.ts.map +1 -1
  181. package/dist/utils/segmenter.js +8 -3
  182. package/dist/utils/segmenter.js.map +1 -1
  183. package/dist/utils/strings.d.ts +1 -1
  184. package/dist/utils/strings.d.ts.map +1 -1
  185. package/dist/utils/strings.js +4 -2
  186. package/dist/utils/strings.js.map +1 -1
  187. package/package.json +1 -1
  188. package/dist/agent/managers/userFactExtractor.d.ts.map +0 -1
  189. package/dist/agent/managers/userFactExtractor.js.map +0 -1
  190. /package/dist/agent/{managers/userFactExtractor.js → userFactExtractor.js} +0 -0
@@ -78,10 +78,6 @@ export declare class PersonaManager {
78
78
  setMode(mode: PersonaMode): void;
79
79
  /** 获取当前激活模式 */
80
80
  get currentMode(): PersonaMode;
81
- /**
82
- * 获取当前激活的角色
83
- */
84
- get active(): Persona | null;
85
81
  /**
86
82
  * 获取角色列表
87
83
  */
@@ -93,6 +89,19 @@ export declare class PersonaManager {
93
89
  * 若不清理,Agent 关闭后定时器仍会触发回调,在已关闭的实例上执行引发异常。
94
90
  */
95
91
  close(): void;
92
+ /**
93
+ * 重载角色:清空内存缓存 + 重新扫描目录 + 同步 SQLite 索引 + 保持当前激活角色
94
+ *
95
+ * 事件驱动重载:confirmConfigSuggestion 写入 persona 文件后或用户手动编辑
96
+ * personas/ 目录后,调用此方法使当前会话立即生效,无需重启 Agent。
97
+ *
98
+ * 激活角色保持策略:
99
+ * - 若当前激活角色在重载后仍存在 → 更新为重载后的版本(内容可能已变更)
100
+ * - 若当前激活角色已被删除 → 回退到列表第一个角色(与 load() 默认行为一致)
101
+ *
102
+ * @returns 重载后的角色数量
103
+ */
104
+ reload(): Promise<number>;
96
105
  /**
97
106
  * 构建 system prompt 中的角色段
98
107
  */
@@ -107,10 +116,14 @@ export declare class PersonaManager {
107
116
  private scanPersonas;
108
117
  /**
109
118
  * 将所有角色写入 SQLite 索引
119
+ *
120
+ * 本函数循环体内无 await,作为同步函数实现。
110
121
  */
111
122
  private writeAllToIndex;
112
123
  /**
113
124
  * 将单个角色写入 SQLite 索引
125
+ *
126
+ * 函数体无 await,作为同步函数实现。index.upsert 是同步方法。
114
127
  */
115
128
  private writePersonaToIndex;
116
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"personaManager.d.ts","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA4B/D;;GAEG;AACH,qBAAa,cAAc;IA0BvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IA1BzB,cAAc;IACd,OAAO,CAAC,aAAa,CAAwB;IAC7C,sBAAsB;IACtB,OAAO,CAAC,WAAW,CAAiB;IACpC,WAAW;IACX,OAAO,CAAC,IAAI,CAAuB;IACnC,0BAA0B;IAC1B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,4BAA4B;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,cAAc;IACd,OAAO,CAAC,WAAW,CAA8C;IAEjE,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAClD,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAK;IACnD,qBAAqB;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAW;IAEjD;;;OAGG;gBAEgB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,KAAK,CAAC,EAAE,cAAc,YAAA;IAGzC;;;;;OAKG;IACG,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqCnD;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;OAIG;IACH,SAAS,IAAI,OAAO,GAAG,IAAI;IAI3B;;;;;;;;;OASG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAyBnC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA8B3C;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAUhC,eAAe;IACf,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,OAAO,GAAG,IAAI,CAE3B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,EAAE,CAEpB;IAED;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAUxC;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;YACW,YAAY;IAyB1B;;OAEG;YACW,eAAe;IAQ7B;;OAEG;YACW,mBAAmB;IAejC;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAU7B"}
1
+ {"version":3,"file":"personaManager.d.ts","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA6B/D;;GAEG;AACH,qBAAa,cAAc;IA0BvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IA1BzB,cAAc;IACd,OAAO,CAAC,aAAa,CAAwB;IAC7C,sBAAsB;IACtB,OAAO,CAAC,WAAW,CAAiB;IACpC,WAAW;IACX,OAAO,CAAC,IAAI,CAAuB;IACnC,0BAA0B;IAC1B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,4BAA4B;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,cAAc;IACd,OAAO,CAAC,WAAW,CAA8C;IAEjE,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAClD,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAK;IACnD,qBAAqB;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAW;IAEjD;;;OAGG;gBAEgB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,KAAK,CAAC,EAAE,cAAc,YAAA;IAGzC;;;;;OAKG;IACG,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqCnD;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;OAIG;IACH,SAAS,IAAI,OAAO,GAAG,IAAI;IAI3B;;;;;;;;;OASG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAyBnC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA8B3C;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAUhC,eAAe;IACf,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,EAAE,CAEpB;IAED;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAOb;;;;;;;;;;;OAWG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IA4B/B;;OAEG;IACH,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAUxC;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;YACW,YAAY;IAyB1B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAU7B"}
@@ -23,6 +23,7 @@ import { logger } from '../logging/logger.js';
23
23
  import { configError } from '../utils/errors.js';
24
24
  import { scanMarkdownDir, parseKeywords, resolveSubdir } from '../utils/scanner.js';
25
25
  import { safeSetTimeout, clearSafeTimeout } from '../utils/safeTimer.js';
26
+ import { nowIso } from '../utils/time.js';
26
27
  /**
27
28
  * 从 frontmatter 解析 traits.* 键值对
28
29
  *
@@ -91,12 +92,12 @@ export class PersonaManager {
91
92
  if (this.personaList.length === 0) {
92
93
  logger.warn({ personaCount: 0 }, '未找到任何角色文件,将使用默认角色');
93
94
  this.activePersona = this.createDefaultPersona();
94
- await this.writePersonaToIndex(this.activePersona);
95
+ this.writePersonaToIndex(this.activePersona);
95
96
  return this.buildSystemPrompt();
96
97
  }
97
98
  logger.info({ count: this.personaList.length, names: this.personaList.map((p) => p.name) }, '角色文件加载完成');
98
99
  // 写入 SQLite 索引(persona 遵循万物皆记忆)
99
- await this.writeAllToIndex();
100
+ this.writeAllToIndex();
100
101
  // 激活指定角色
101
102
  if (activePersona) {
102
103
  const found = this.personaList.find((p) => p.name === activePersona);
@@ -221,12 +222,6 @@ export class PersonaManager {
221
222
  get currentMode() {
222
223
  return this.mode;
223
224
  }
224
- /**
225
- * 获取当前激活的角色
226
- */
227
- get active() {
228
- return this.activePersona;
229
- }
230
225
  /**
231
226
  * 获取角色列表
232
227
  */
@@ -245,6 +240,39 @@ export class PersonaManager {
245
240
  this.unlockTimer = null;
246
241
  }
247
242
  }
243
+ /**
244
+ * 重载角色:清空内存缓存 + 重新扫描目录 + 同步 SQLite 索引 + 保持当前激活角色
245
+ *
246
+ * 事件驱动重载:confirmConfigSuggestion 写入 persona 文件后或用户手动编辑
247
+ * personas/ 目录后,调用此方法使当前会话立即生效,无需重启 Agent。
248
+ *
249
+ * 激活角色保持策略:
250
+ * - 若当前激活角色在重载后仍存在 → 更新为重载后的版本(内容可能已变更)
251
+ * - 若当前激活角色已被删除 → 回退到列表第一个角色(与 load() 默认行为一致)
252
+ *
253
+ * @returns 重载后的角色数量
254
+ */
255
+ async reload() {
256
+ const oldActiveName = this.activePersona?.name;
257
+ this.personaList = await this.scanPersonas();
258
+ this.writeAllToIndex();
259
+ // 保持当前激活角色(若仍存在),否则回退到第一个
260
+ if (oldActiveName) {
261
+ const found = this.personaList.find((p) => p.name === oldActiveName);
262
+ if (found) {
263
+ this.activePersona = found;
264
+ }
265
+ else {
266
+ this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
267
+ logger.warn({ oldActive: oldActiveName, newActive: this.activePersona.name }, '激活角色已被删除,回退到默认');
268
+ }
269
+ }
270
+ else {
271
+ this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
272
+ }
273
+ logger.info({ count: this.personaList.length, active: this.activePersona.name }, '角色已重载');
274
+ return this.personaList.length;
275
+ }
248
276
  /**
249
277
  * 构建 system prompt 中的角色段
250
278
  */
@@ -305,22 +333,26 @@ export class PersonaManager {
305
333
  }
306
334
  /**
307
335
  * 将所有角色写入 SQLite 索引
336
+ *
337
+ * 本函数循环体内无 await,作为同步函数实现。
308
338
  */
309
- async writeAllToIndex() {
339
+ writeAllToIndex() {
310
340
  if (!this.index)
311
341
  return;
312
342
  for (const persona of this.personaList) {
313
- await this.writePersonaToIndex(persona);
343
+ this.writePersonaToIndex(persona);
314
344
  }
315
345
  logger.info({ count: this.personaList.length }, '角色记忆已写入 SQLite');
316
346
  }
317
347
  /**
318
348
  * 将单个角色写入 SQLite 索引
349
+ *
350
+ * 函数体无 await,作为同步函数实现。index.upsert 是同步方法。
319
351
  */
320
- async writePersonaToIndex(persona) {
352
+ writePersonaToIndex(persona) {
321
353
  if (!this.index)
322
354
  return;
323
- const now = new Date().toISOString();
355
+ const now = nowIso();
324
356
  const memory = {
325
357
  id: persona.id,
326
358
  content: persona.content,
@@ -1 +1 @@
1
- {"version":3,"file":"personaManager.js","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"personaManager.js","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ export interface AuditEvent {
7
7
  path: string;
8
8
  /** 工具名(read_file / write_file / 自定义工具名) */
9
9
  tool?: string;
10
- /** S-02: 调用链来源(builtin / custom / system),标记安全检查的触发方 */
10
+ /** 调用链来源(builtin / custom / system),标记安全检查的触发方 */
11
11
  source?: 'builtin' | 'custom' | 'system';
12
12
  /** 用户决策(写入二次确认场景) */
13
13
  decision?: WriteDecision;
@@ -43,6 +43,10 @@ export interface WriteConfirmationInfo {
43
43
  permission: Permission;
44
44
  /** 是否需要确认(owner + confirmWrites=false 时为 false,宿主可跳过弹窗) */
45
45
  needsConfirm: boolean;
46
+ /** 文件当前内容预览(截断到 10KB,null 表示新文件)—— 供宿主 UI 展示 diff */
47
+ beforeContent?: string | null;
48
+ /** 写入后内容预览(截断到 10KB)—— 供宿主 UI 展示 diff */
49
+ afterContent?: string;
46
50
  }
47
51
  export declare class SecurityGuard {
48
52
  /** owner 是否启用写入二次确认;guest 强制开启 */
@@ -96,23 +100,41 @@ export declare class SecurityGuard {
96
100
  /**
97
101
  * 断言路径允许访问
98
102
  * @throws Error 不在白名单时
99
- * @param source S-02: 调用链来源标记
103
+ * @param source 调用链来源标记
100
104
  */
101
105
  assertPathAllowed(absolutePath: string, tool?: string, source?: 'builtin' | 'custom' | 'system'): void;
102
106
  /**
103
- * 写入操作前请求用户确认(M-101)
107
+ * 写入操作前请求用户确认
104
108
  *
105
109
  * 规则:
106
110
  * - guest 模式:始终要求确认
107
111
  * - owner + confirmWrites=true:要求确认
108
112
  * - owner + confirmWrites=false:自动批准
109
113
  *
110
- * 优先走 confirmationHandler 注入式回调(宿主程序),
111
- * 未注册时回退到 readline + stdin(CLI 场景)。
114
+ * 决策(fail-closed):
115
+ * - 需要确认时,必须通过 onWriteConfirmation() 注入 confirmationHandler
116
+ * - 未注入 handler 时,**直接拒绝写入**(返回 false)
117
+ * - 理由:内核纯逻辑库不应依赖交互式终端 I/O;宿主程序负责提供确认 UI
118
+ * - 安全优先:未配置 = 拒绝,避免无意识放行
112
119
  *
113
- * @returns true 确认通过;false 用户拒绝
120
+ * @returns true 确认通过;false 用户拒绝或未注入 handler(fail-closed)
114
121
  */
115
- requestWriteConfirmation(targetPath: string, tool: string, description?: string): Promise<boolean>;
122
+ requestWriteConfirmation(targetPath: string, tool: string, description?: string,
123
+ /** diff 内容选项(供宿主 UI 展示变更预览,自动截断到 10KB) */
124
+ options?: {
125
+ beforeContent?: string | null;
126
+ afterContent?: string;
127
+ }): Promise<boolean>;
128
+ /**
129
+ * 通过宿主注入的 confirmationHandler 进行写入确认
130
+ *
131
+ * 从 requestWriteConfirmation 拆分。抛错视为拒绝(fail-closed 安全优先)。
132
+ * 此方法是唯一的确认执行路径。
133
+ *
134
+ * @param info 确认信息(含 diff 内容)
135
+ * @returns true 确认通过;false 用户拒绝或回调异常
136
+ */
137
+ private confirmViaHandler;
116
138
  /**
117
139
  * 触发审计事件 + 写入日志 + 通知订阅者
118
140
  */
@@ -1 +1 @@
1
- {"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"AAkCA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAC3C,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,GAAG,aAAa,CAAC;AAEvF,MAAM,WAAW,UAAU;IACzB,WAAW;IACX,IAAI,EAAE,YAAY,GAAG,WAAW,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAC;IACpF,cAAc;IACd,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzC,qBAAqB;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEzF,gBAAgB;AAChB,MAAM,WAAW,qBAAqB;IACpC,eAAe;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,2DAA2D;IAC3D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,aAAa;IAmBtB,kCAAkC;aAClB,aAAa,EAAE,OAAO;IACtC,WAAW;aACK,UAAU,EAAE,UAAU;IArBxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,4BAA4B;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;IACnC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB,CAAyC;IAEpE,sBAAsB;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;gBAGtC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,MAAM,EAAO;IAChC,kCAAkC;IAClB,aAAa,GAAE,OAAe;IAC9C,WAAW;IACK,UAAU,GAAE,UAAoB;IAChD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM;IAClB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM;IAkBvB;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,GAAG,IAAI;IAInE;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAQ5C;;OAEG;IACH,eAAe,CAAC,KAAK,SAAK,GAAG,UAAU,EAAE;IAIzC;;;;OAIG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAoDtG;;;;;;;;;;;;OAYG;IACG,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC;IAoFnB;;OAEG;IACH,OAAO,CAAC,SAAS;CAuBlB"}
1
+ {"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"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"}
@@ -1,35 +1,100 @@
1
1
  /**
2
2
  * 路径白名单 + 审计日志
3
3
  *
4
- * 4 类允许 + 12 类禁止
4
+ * 4 类允许根 + 27 类禁止规则
5
5
  * 详见 ADR-006 · 安全模型
6
- * 阶段二新增:M-101 写入二次确认 + M-105 审计日志
6
+ *
7
+ * 写入二次确认 + 审计日志:未注入 confirmationHandler 时 fail-closed 拒绝写入。
8
+ * 内核纯逻辑库不应依赖交互式终端 I/O(node:readline/promises + node:process),
9
+ * 宿主程序应通过 onWriteConfirmation() 注入自己的确认 UI(Electron/Web/CLI 各自实现)。
7
10
  */
8
- import { resolve, sep } from 'node:path';
9
- import { createInterface } from 'node:readline/promises';
10
- import { stdin, stdout } from 'node:process';
11
+ import { resolve, sep, dirname, basename, join } from 'node:path';
12
+ import { realpathSync } from 'node:fs';
11
13
  import { logger } from '../logging/logger.js';
12
14
  import { securityError, toError } from '../utils/errors.js';
13
15
  import { expandHome } from '../utils/path.js';
16
+ import { nowIso } from '../utils/time.js';
17
+ /**
18
+ * 解析路径的真实绝对路径(解析符号链接链)
19
+ *
20
+ * 安全考量:若不解析符号链接,攻击者可在项目内放置指向 /etc 的符号链接,
21
+ * 绕过白名单前缀匹配访问任意系统目录(P0 符号链接逃逸漏洞)。
22
+ *
23
+ * 策略:
24
+ * - 路径存在时:realpathSync 解析完整符号链接链
25
+ * - 路径不存在时(写入新文件场景):逐级向上查找已存在的父目录并 realpath,再拼接不存在部分
26
+ * - 全程不存在时:回退到 resolve()(白名单/黑名单仍会兜底校验)
27
+ *
28
+ * @param p 任意路径(相对或绝对)
29
+ * @returns 解析符号链接后的真实绝对路径
30
+ */
31
+ function resolveRealpath(p) {
32
+ const resolved = resolve(p);
33
+ try {
34
+ return realpathSync(resolved);
35
+ }
36
+ catch {
37
+ // 路径不存在 - 递归解析已存在的父目录
38
+ const parent = dirname(resolved);
39
+ const base = basename(resolved);
40
+ try {
41
+ const realParent = realpathSync(parent);
42
+ return join(realParent, base);
43
+ }
44
+ catch {
45
+ // 父目录也不存在 - 继续向上递归
46
+ const realGrandParent = resolveRealpath(parent);
47
+ return join(realGrandParent, base);
48
+ }
49
+ }
50
+ }
14
51
  const BLOCKED_PATTERNS = [
15
- // 系统凭证
52
+ // ─── 系统凭证文件(跨平台,路径段匹配)───
16
53
  /(^|[\\/])\.ssh([\\/]|$)/i,
17
54
  /(^|[\\/])\.gnupg([\\/]|$)/i,
18
55
  /(^|[\\/])\.netrc$/i,
19
56
  /(^|[\\/])\.pgpass$/i,
20
- /[\\/]etc[\\/]passwd/i,
21
- // 云服务凭证
57
+ // ─── 包管理器凭证 ───
58
+ /(^|[\\/])\.gitconfig$/i, // Git 配置(可能含 credential helper token)
59
+ /(^|[\\/])\.git-credentials$/i, // Git credential store 明文存储
60
+ /(^|[\\/])\.npmrc$/i, // npm authToken
61
+ /(^|[\\/])\.pypirc$/i, // PyPI 上传凭证
62
+ /(^|[\\/])\.gem[\\/]credentials$/i, // RubyGems push 凭证
63
+ /(^|[\\/])\.composer[\\/]auth\.json$/i, // Composer 凭证
64
+ /(^|[\\/])\.htpasswd$/i, // Apache Basic Auth 凭证
65
+ // ─── Linux/macOS 特定凭证文件(向后兼容保留)───
66
+ /[\\/]etc[\\/]passwd/i, // 用户密码哈希
67
+ /[\\/]etc[\\/]shadow/i,
68
+ /[\\/]etc[\\/]gshadow/i, // 组密码哈希
69
+ /[\\/]etc[\\/]sudoers/i, // sudo 配置
70
+ // ─── 云服务凭证 ───
22
71
  /(^|[\\/])\.aws([\\/]|$)/i,
23
72
  /(^|[\\/])\.azure([\\/]|$)/i,
24
73
  /(^|[\\/])\.docker([\\/]|$)/i,
25
74
  /(^|[\\/])\.kube([\\/]|$)/i,
26
- /[\\/]gcloud([\\/]|$)/i,
27
- // 仅拦截纯 `.env`、`.env.<name>`(name 不含 .)。
28
- /(^|[\\/])\.env$|(^|[\\/])\.env\.[^\\/.]+$/i,
29
- // 系统目录
30
- /[\\/]system32([\\/]|$)/i,
31
- /[\\/]Windows[\\/]System/i,
75
+ /(^|[\\/])\.config[\\/]gcloud([\\/]|$)/i, // gcloud 配置(加 .config 前缀边界,避免误拦用户 gcloud-tools 目录)
76
+ // ─── 环境变量文件(.env / .env.local / .env.production.local 等多段后缀)───
77
+ /(^|[\\/])\.env(\.[^\\/]+)?$/i,
78
+ // ─── Windows 系统目录 ───
79
+ /[\\/]Windows([\\/]|$)/i, // C:\Windows(含 System、System32 等子目录)
80
+ /[\\/]Program Files([\\/]|$)/i, // C:\Program Files
81
+ /[\\/]Program Files \(x86\)([\\/]|$)/i, // C:\Program Files (x86)
82
+ /[\\/]ProgramData([\\/]|$)/i, // C:\ProgramData(系统级应用数据)
83
+ // ─── Linux/macOS 系统目录(根目录锚定 ^/,避免误伤项目内同名目录)───
84
+ /^\/(etc|usr|bin|sbin|var|root|home|lib|lib64|opt)([\\/]|$)/i,
85
+ // ─── Linux/macOS 虚拟文件系统 + 启动目录(根目录锚定)───
86
+ /^\/(proc|sys|boot)([\\/]|$)/i,
32
87
  ];
88
+ /** diff 内容最大长度(10KB),防止大文件内容撑爆 IPC 传输和 UI 渲染 */
89
+ const MAX_DIFF_CONTENT_LENGTH = 10240;
90
+ function truncateForDiff(content) {
91
+ if (content === null || content === undefined)
92
+ return content;
93
+ if (content.length <= MAX_DIFF_CONTENT_LENGTH)
94
+ return content;
95
+ // 超过上限时截断并追加标记,让用户知道内容被裁剪
96
+ return content.slice(0, MAX_DIFF_CONTENT_LENGTH) + `\n...(已截断,共 ${content.length} 字符)`;
97
+ }
33
98
  export class SecurityGuard {
34
99
  confirmWrites;
35
100
  permission;
@@ -56,19 +121,20 @@ export class SecurityGuard {
56
121
  agentDataDir) {
57
122
  this.confirmWrites = confirmWrites;
58
123
  this.permission = permission;
59
- // 构建白名单根目录列表
124
+ // 构建白名单根目录列表:使用 resolveRealpath 解析符号链接,
125
+ // 确保白名单基准是真实路径,与 assertPathAllowed 中的 resolveRealpath 对齐
60
126
  this.allowedRoots = [
61
- resolve(projectPath),
62
- resolve(expandHome(memoraDir)),
127
+ resolveRealpath(expandHome(projectPath)),
128
+ resolveRealpath(expandHome(memoraDir)),
63
129
  ];
64
130
  if (configDir) {
65
- this.allowedRoots.push(resolve(expandHome(configDir)));
131
+ this.allowedRoots.push(resolveRealpath(expandHome(configDir)));
66
132
  }
67
133
  if (agentDataDir) {
68
- this.allowedRoots.push(resolve(expandHome(agentDataDir)));
134
+ this.allowedRoots.push(resolveRealpath(expandHome(agentDataDir)));
69
135
  }
70
136
  for (const p of extraAllowedPaths) {
71
- this.allowedRoots.push(resolve(expandHome(p)));
137
+ this.allowedRoots.push(resolveRealpath(expandHome(p)));
72
138
  }
73
139
  }
74
140
  /**
@@ -108,12 +174,13 @@ export class SecurityGuard {
108
174
  /**
109
175
  * 断言路径允许访问
110
176
  * @throws Error 不在白名单时
111
- * @param source S-02: 调用链来源标记
177
+ * @param source 调用链来源标记
112
178
  */
113
179
  assertPathAllowed(absolutePath, tool, source) {
114
- // SEC-05: NFKC 规范化,防止全角字符(如 ../)绕过黑名单正则
180
+ // NFKC 规范化,防止全角字符(如 ../)绕过黑名单正则
115
181
  const normalized = absolutePath.normalize('NFKC');
116
- const resolved = resolve(normalized);
182
+ // resolveRealpath 解析符号链接,防止通过项目内符号链接逃逸到系统目录
183
+ const resolved = resolveRealpath(normalized);
117
184
  // 1. 黑名单优先
118
185
  for (const pattern of BLOCKED_PATTERNS) {
119
186
  if (pattern.test(resolved)) {
@@ -123,7 +190,7 @@ export class SecurityGuard {
123
190
  tool,
124
191
  source,
125
192
  reason: `命中黑名单规则 (${pattern})`,
126
- timestamp: new Date().toISOString(),
193
+ timestamp: nowIso(),
127
194
  });
128
195
  throw securityError('禁止访问:路径命中黑名单', `路径 ${resolved} 命中黑名单规则 (${pattern})`, ['检查路径是否正确', '如需访问该路径,请联系管理员添加白名单']);
129
196
  }
@@ -136,7 +203,7 @@ export class SecurityGuard {
136
203
  path: resolved,
137
204
  tool,
138
205
  source,
139
- timestamp: new Date().toISOString(),
206
+ timestamp: nowIso(),
140
207
  });
141
208
  return;
142
209
  }
@@ -147,7 +214,7 @@ export class SecurityGuard {
147
214
  tool,
148
215
  source,
149
216
  reason: '路径越界,不在白名单内',
150
- timestamp: new Date().toISOString(),
217
+ timestamp: nowIso(),
151
218
  });
152
219
  throw securityError('路径越界', `${resolved} 不在白名单内`, [
153
220
  '检查路径是否在项目目录内',
@@ -155,96 +222,96 @@ export class SecurityGuard {
155
222
  ]);
156
223
  }
157
224
  /**
158
- * 写入操作前请求用户确认(M-101)
225
+ * 写入操作前请求用户确认
159
226
  *
160
227
  * 规则:
161
228
  * - guest 模式:始终要求确认
162
229
  * - owner + confirmWrites=true:要求确认
163
230
  * - owner + confirmWrites=false:自动批准
164
231
  *
165
- * 优先走 confirmationHandler 注入式回调(宿主程序),
166
- * 未注册时回退到 readline + stdin(CLI 场景)。
232
+ * 决策(fail-closed):
233
+ * - 需要确认时,必须通过 onWriteConfirmation() 注入 confirmationHandler
234
+ * - 未注入 handler 时,**直接拒绝写入**(返回 false)
235
+ * - 理由:内核纯逻辑库不应依赖交互式终端 I/O;宿主程序负责提供确认 UI
236
+ * - 安全优先:未配置 = 拒绝,避免无意识放行
167
237
  *
168
- * @returns true 确认通过;false 用户拒绝
238
+ * @returns true 确认通过;false 用户拒绝或未注入 handler(fail-closed)
169
239
  */
170
- async requestWriteConfirmation(targetPath, tool, description) {
240
+ async requestWriteConfirmation(targetPath, tool, description,
241
+ /** diff 内容选项(供宿主 UI 展示变更预览,自动截断到 10KB) */
242
+ options) {
171
243
  const needConfirm = this.permission === 'guest' || this.confirmWrites;
244
+ // 无需确认:直接放行并记录审计
172
245
  if (!needConfirm) {
173
246
  this.emitAudit({
174
247
  type: 'write-auto',
175
248
  path: targetPath,
176
249
  tool,
177
250
  decision: 'auto-approved',
178
- timestamp: new Date().toISOString(),
251
+ timestamp: nowIso(),
179
252
  });
180
253
  return true;
181
254
  }
255
+ // 构建确认信息(透传 diff 内容,供宿主 UI 展示变更预览)
182
256
  const info = {
183
257
  targetPath,
184
258
  tool,
185
259
  description,
186
260
  permission: this.permission,
187
261
  needsConfirm: needConfirm,
262
+ beforeContent: truncateForDiff(options?.beforeContent),
263
+ afterContent: truncateForDiff(options?.afterContent),
188
264
  };
189
- if (this.confirmationHandler) {
190
- try {
191
- const ok = await this.confirmationHandler(info);
192
- this.emitAudit({
193
- type: ok ? 'write-confirm' : 'write-decline',
194
- path: targetPath,
195
- tool,
196
- decision: ok ? 'confirmed' : 'declined',
197
- timestamp: new Date().toISOString(),
198
- });
199
- return ok;
200
- }
201
- catch (err) {
202
- // 抛错视为拒绝(fail-closed 安全优先)
203
- logger.warn({ err, targetPath }, '写入确认回调异常,视为拒绝');
204
- this.emitAudit({
205
- type: 'write-decline',
206
- path: targetPath,
207
- tool,
208
- decision: 'declined',
209
- reason: `回调异常:${toError(err).message}`,
210
- timestamp: new Date().toISOString(),
211
- });
212
- return false;
213
- }
265
+ // 未注入 confirmationHandler 时 fail-closed 拒绝
266
+ if (!this.confirmationHandler) {
267
+ logger.warn({ targetPath, tool, permission: this.permission }, '写入确认失败:未注入 confirmationHandler,fail-closed 拒绝写入');
268
+ this.emitAudit({
269
+ type: 'write-decline',
270
+ path: targetPath,
271
+ tool,
272
+ decision: 'declined',
273
+ reason: '未注入 confirmationHandler(fail-closed)',
274
+ timestamp: nowIso(),
275
+ });
276
+ return false;
214
277
  }
215
- // 回退:CLI 场景直接走终端 readline
216
- const rl = createInterface({ input: stdin, output: stdout });
278
+ // 走宿主注入的 confirmationHandler(此处 handler 必非空,上方已 fail-closed 拦截)
279
+ return this.confirmViaHandler(info, targetPath, tool);
280
+ }
281
+ /**
282
+ * 通过宿主注入的 confirmationHandler 进行写入确认
283
+ *
284
+ * 从 requestWriteConfirmation 拆分。抛错视为拒绝(fail-closed 安全优先)。
285
+ * 此方法是唯一的确认执行路径。
286
+ *
287
+ * @param info 确认信息(含 diff 内容)
288
+ * @returns true 确认通过;false 用户拒绝或回调异常
289
+ */
290
+ async confirmViaHandler(info, targetPath, tool) {
217
291
  try {
218
- const lines = [
219
- `\n🔒 写入二次确认 [${this.permission}]`,
220
- ` 工具: ${tool}`,
221
- ` 路径: ${targetPath}`,
222
- ...(description ? [` 说明: ${description}`] : []),
223
- ` 确认写入?(y/N) `,
224
- ];
225
- const answer = (await rl.question(lines.join('\n'))).trim().toLowerCase();
226
- if (answer === 'y' || answer === 'yes') {
227
- this.emitAudit({
228
- type: 'write-confirm',
229
- path: targetPath,
230
- tool,
231
- decision: 'confirmed',
232
- timestamp: new Date().toISOString(),
233
- });
234
- return true;
235
- }
292
+ const ok = await this.confirmationHandler(info);
293
+ this.emitAudit({
294
+ type: ok ? 'write-confirm' : 'write-decline',
295
+ path: targetPath,
296
+ tool,
297
+ decision: ok ? 'confirmed' : 'declined',
298
+ timestamp: nowIso(),
299
+ });
300
+ return ok;
301
+ }
302
+ catch (err) {
303
+ // 抛错视为拒绝(fail-closed 安全优先)
304
+ logger.warn({ err, targetPath }, '写入确认回调异常,视为拒绝');
236
305
  this.emitAudit({
237
306
  type: 'write-decline',
238
307
  path: targetPath,
239
308
  tool,
240
309
  decision: 'declined',
241
- timestamp: new Date().toISOString(),
310
+ reason: `回调异常:${toError(err).message}`,
311
+ timestamp: nowIso(),
242
312
  });
243
313
  return false;
244
314
  }
245
- finally {
246
- rl.close();
247
- }
248
315
  }
249
316
  /**
250
317
  * 触发审计事件 + 写入日志 + 通知订阅者