@zooique/memora 2.0.0 → 3.0.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 (588) hide show
  1. package/CHANGELOG.md +1028 -0
  2. package/README.en.md +305 -0
  3. package/README.md +303 -148
  4. package/config.example.json +43 -0
  5. package/dist/agent/agent.d.ts +438 -295
  6. package/dist/agent/agent.d.ts.map +1 -1
  7. package/dist/agent/agent.js +1368 -836
  8. package/dist/agent/agent.js.map +1 -1
  9. package/dist/agent/assembler.d.ts +117 -39
  10. package/dist/agent/assembler.d.ts.map +1 -1
  11. package/dist/agent/assembler.js +574 -71
  12. package/dist/agent/assembler.js.map +1 -1
  13. package/dist/agent/budget.d.ts +131 -0
  14. package/dist/agent/budget.d.ts.map +1 -0
  15. package/dist/agent/budget.js +128 -0
  16. package/dist/agent/budget.js.map +1 -0
  17. package/dist/agent/builtinToolHandlers.d.ts +229 -17
  18. package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
  19. package/dist/agent/builtinToolHandlers.js +758 -70
  20. package/dist/agent/builtinToolHandlers.js.map +1 -1
  21. package/dist/agent/builtinTools.d.ts +198 -7
  22. package/dist/agent/builtinTools.d.ts.map +1 -1
  23. package/dist/agent/builtinTools.js +646 -14
  24. package/dist/agent/builtinTools.js.map +1 -1
  25. package/dist/agent/compaction.d.ts +93 -0
  26. package/dist/agent/compaction.d.ts.map +1 -0
  27. package/dist/agent/compaction.js +192 -0
  28. package/dist/agent/compaction.js.map +1 -0
  29. package/dist/agent/constants.d.ts +139 -18
  30. package/dist/agent/constants.d.ts.map +1 -1
  31. package/dist/agent/constants.js +154 -18
  32. package/dist/agent/constants.js.map +1 -1
  33. package/dist/agent/contextManager.d.ts +126 -76
  34. package/dist/agent/contextManager.d.ts.map +1 -1
  35. package/dist/agent/contextManager.js +197 -135
  36. package/dist/agent/contextManager.js.map +1 -1
  37. package/dist/agent/contextPreparer.d.ts +78 -0
  38. package/dist/agent/contextPreparer.d.ts.map +1 -0
  39. package/dist/agent/contextPreparer.js +128 -0
  40. package/dist/agent/contextPreparer.js.map +1 -0
  41. package/dist/agent/duplicateInterceptor.d.ts +67 -0
  42. package/dist/agent/duplicateInterceptor.d.ts.map +1 -0
  43. package/dist/agent/duplicateInterceptor.js +82 -0
  44. package/dist/agent/duplicateInterceptor.js.map +1 -0
  45. package/dist/agent/guardRail.d.ts +166 -0
  46. package/dist/agent/guardRail.d.ts.map +1 -0
  47. package/dist/agent/guardRail.js +333 -0
  48. package/dist/agent/guardRail.js.map +1 -0
  49. package/dist/agent/loop.d.ts +718 -253
  50. package/dist/agent/loop.d.ts.map +1 -1
  51. package/dist/agent/loop.js +2215 -648
  52. package/dist/agent/loop.js.map +1 -1
  53. package/dist/agent/managers/archiveCoordinator.d.ts +21 -74
  54. package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
  55. package/dist/agent/managers/archiveCoordinator.js +32 -105
  56. package/dist/agent/managers/archiveCoordinator.js.map +1 -1
  57. package/dist/agent/managers/chatLockManager.d.ts +20 -88
  58. package/dist/agent/managers/chatLockManager.d.ts.map +1 -1
  59. package/dist/agent/managers/chatLockManager.js +31 -103
  60. package/dist/agent/managers/chatLockManager.js.map +1 -1
  61. package/dist/agent/managers/dedupManager.d.ts +85 -0
  62. package/dist/agent/managers/dedupManager.d.ts.map +1 -0
  63. package/dist/agent/managers/dedupManager.js +248 -0
  64. package/dist/agent/managers/dedupManager.js.map +1 -0
  65. package/dist/agent/managers/goalConsistencyChecker.d.ts +42 -0
  66. package/dist/agent/managers/goalConsistencyChecker.d.ts.map +1 -0
  67. package/dist/agent/managers/goalConsistencyChecker.js +178 -0
  68. package/dist/agent/managers/goalConsistencyChecker.js.map +1 -0
  69. package/dist/agent/managers/llmCaller.d.ts +124 -0
  70. package/dist/agent/managers/llmCaller.d.ts.map +1 -0
  71. package/dist/agent/managers/llmCaller.js +417 -0
  72. package/dist/agent/managers/llmCaller.js.map +1 -0
  73. package/dist/agent/managers/llmJudgeHelper.d.ts +21 -0
  74. package/dist/agent/managers/llmJudgeHelper.d.ts.map +1 -0
  75. package/dist/agent/managers/llmJudgeHelper.js +32 -0
  76. package/dist/agent/managers/llmJudgeHelper.js.map +1 -0
  77. package/dist/agent/managers/loopMetrics.d.ts +58 -0
  78. package/dist/agent/managers/loopMetrics.d.ts.map +1 -0
  79. package/dist/agent/managers/loopMetrics.js +68 -0
  80. package/dist/agent/managers/loopMetrics.js.map +1 -0
  81. package/dist/agent/managers/memoryAdvisor.d.ts +27 -120
  82. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
  83. package/dist/agent/managers/memoryAdvisor.js +56 -192
  84. package/dist/agent/managers/memoryAdvisor.js.map +1 -1
  85. package/dist/agent/managers/memoryGovernance.d.ts +24 -0
  86. package/dist/agent/managers/memoryGovernance.d.ts.map +1 -0
  87. package/dist/agent/managers/memoryGovernance.js +46 -0
  88. package/dist/agent/managers/memoryGovernance.js.map +1 -0
  89. package/dist/agent/managers/memoryInspector.d.ts +59 -393
  90. package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
  91. package/dist/agent/managers/memoryInspector.js +92 -736
  92. package/dist/agent/managers/memoryInspector.js.map +1 -1
  93. package/dist/agent/managers/roundSummaryGenerator.d.ts +56 -0
  94. package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -0
  95. package/dist/agent/managers/roundSummaryGenerator.js +201 -0
  96. package/dist/agent/managers/roundSummaryGenerator.js.map +1 -0
  97. package/dist/agent/managers/sessionArchiver.d.ts +19 -63
  98. package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
  99. package/dist/agent/managers/sessionArchiver.js +83 -157
  100. package/dist/agent/managers/sessionArchiver.js.map +1 -1
  101. package/dist/agent/managers/sessionManager.d.ts +286 -57
  102. package/dist/agent/managers/sessionManager.d.ts.map +1 -1
  103. package/dist/agent/managers/sessionManager.js +846 -85
  104. package/dist/agent/managers/sessionManager.js.map +1 -1
  105. package/dist/agent/managers/sessionNamer.d.ts +35 -0
  106. package/dist/agent/managers/sessionNamer.d.ts.map +1 -0
  107. package/dist/agent/managers/sessionNamer.js +104 -0
  108. package/dist/agent/managers/sessionNamer.js.map +1 -0
  109. package/dist/agent/managers/streamAccumulator.d.ts +20 -0
  110. package/dist/agent/managers/streamAccumulator.d.ts.map +1 -0
  111. package/dist/agent/managers/streamAccumulator.js +15 -0
  112. package/dist/agent/managers/streamAccumulator.js.map +1 -0
  113. package/dist/agent/managers/textPolishManager.d.ts +8 -44
  114. package/dist/agent/managers/textPolishManager.d.ts.map +1 -1
  115. package/dist/agent/managers/textPolishManager.js +12 -47
  116. package/dist/agent/managers/textPolishManager.js.map +1 -1
  117. package/dist/agent/managers/toolCallHelpers.d.ts +105 -0
  118. package/dist/agent/managers/toolCallHelpers.d.ts.map +1 -0
  119. package/dist/agent/managers/toolCallHelpers.js +161 -0
  120. package/dist/agent/managers/toolCallHelpers.js.map +1 -0
  121. package/dist/agent/managers/workProjection.d.ts +57 -87
  122. package/dist/agent/managers/workProjection.d.ts.map +1 -1
  123. package/dist/agent/managers/workProjection.js +166 -246
  124. package/dist/agent/managers/workProjection.js.map +1 -1
  125. package/dist/agent/messageHistory.d.ts +134 -84
  126. package/dist/agent/messageHistory.d.ts.map +1 -1
  127. package/dist/agent/messageHistory.js +419 -133
  128. package/dist/agent/messageHistory.js.map +1 -1
  129. package/dist/agent/needsPlanning.d.ts +28 -0
  130. package/dist/agent/needsPlanning.d.ts.map +1 -0
  131. package/dist/agent/needsPlanning.js +68 -0
  132. package/dist/agent/needsPlanning.js.map +1 -0
  133. package/dist/agent/seed/index.d.ts +11 -0
  134. package/dist/agent/seed/index.d.ts.map +1 -0
  135. package/dist/agent/seed/index.js +10 -0
  136. package/dist/agent/seed/index.js.map +1 -0
  137. package/dist/agent/seed/orchestrator.d.ts +83 -0
  138. package/dist/agent/seed/orchestrator.d.ts.map +1 -0
  139. package/dist/agent/seed/orchestrator.js +260 -0
  140. package/dist/agent/seed/orchestrator.js.map +1 -0
  141. package/dist/agent/seed/prepare.d.ts +49 -0
  142. package/dist/agent/seed/prepare.d.ts.map +1 -0
  143. package/dist/agent/seed/prepare.js +107 -0
  144. package/dist/agent/seed/prepare.js.map +1 -0
  145. package/dist/agent/seed/types.d.ts +115 -0
  146. package/dist/agent/seed/types.d.ts.map +1 -0
  147. package/dist/agent/seed/types.js +15 -0
  148. package/dist/agent/seed/types.js.map +1 -0
  149. package/dist/agent/sessionStateMachine.d.ts +78 -0
  150. package/dist/agent/sessionStateMachine.d.ts.map +1 -0
  151. package/dist/agent/sessionStateMachine.js +182 -0
  152. package/dist/agent/sessionStateMachine.js.map +1 -0
  153. package/dist/agent/taskTableRenderer.d.ts +51 -0
  154. package/dist/agent/taskTableRenderer.d.ts.map +1 -0
  155. package/dist/agent/taskTableRenderer.js +115 -0
  156. package/dist/agent/taskTableRenderer.js.map +1 -0
  157. package/dist/agent/toolExecutor.d.ts +255 -9
  158. package/dist/agent/toolExecutor.d.ts.map +1 -1
  159. package/dist/agent/toolExecutor.js +956 -20
  160. package/dist/agent/toolExecutor.js.map +1 -1
  161. package/dist/agent/toolLedger.d.ts +120 -0
  162. package/dist/agent/toolLedger.d.ts.map +1 -0
  163. package/dist/agent/toolLedger.js +149 -0
  164. package/dist/agent/toolLedger.js.map +1 -0
  165. package/dist/agent/toolResultCache.d.ts +134 -0
  166. package/dist/agent/toolResultCache.d.ts.map +1 -0
  167. package/dist/agent/toolResultCache.js +243 -0
  168. package/dist/agent/toolResultCache.js.map +1 -0
  169. package/dist/agent/toolResultOffload.d.ts +59 -0
  170. package/dist/agent/toolResultOffload.d.ts.map +1 -0
  171. package/dist/agent/toolResultOffload.js +70 -0
  172. package/dist/agent/toolResultOffload.js.map +1 -0
  173. package/dist/agent/toolRunner.d.ts +59 -0
  174. package/dist/agent/toolRunner.d.ts.map +1 -0
  175. package/dist/agent/toolRunner.js +147 -0
  176. package/dist/agent/toolRunner.js.map +1 -0
  177. package/dist/agent/tracer.d.ts +99 -107
  178. package/dist/agent/tracer.d.ts.map +1 -1
  179. package/dist/agent/tracer.js +24 -69
  180. package/dist/agent/tracer.js.map +1 -1
  181. package/dist/agent/types.d.ts +512 -162
  182. package/dist/agent/types.d.ts.map +1 -1
  183. package/dist/agent/types.js +2 -51
  184. package/dist/agent/types.js.map +1 -1
  185. package/dist/code-exec/codeExecutionProvider.d.ts +16 -0
  186. package/dist/code-exec/codeExecutionProvider.d.ts.map +1 -0
  187. package/dist/code-exec/codeExecutionProvider.js +57 -0
  188. package/dist/code-exec/codeExecutionProvider.js.map +1 -0
  189. package/dist/code-exec/types.d.ts +37 -0
  190. package/dist/code-exec/types.d.ts.map +1 -0
  191. package/dist/code-exec/types.js +12 -0
  192. package/dist/code-exec/types.js.map +1 -0
  193. package/dist/config/expandEnvVars.d.ts +22 -0
  194. package/dist/config/expandEnvVars.d.ts.map +1 -0
  195. package/dist/config/expandEnvVars.js +38 -0
  196. package/dist/config/expandEnvVars.js.map +1 -0
  197. package/dist/config/loader.d.ts +59 -242
  198. package/dist/config/loader.d.ts.map +1 -1
  199. package/dist/config/loader.js +237 -194
  200. package/dist/config/loader.js.map +1 -1
  201. package/dist/index.d.ts +69 -74
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +93 -63
  204. package/dist/index.js.map +1 -1
  205. package/dist/llm/abortSignal.d.ts +2 -3
  206. package/dist/llm/abortSignal.d.ts.map +1 -1
  207. package/dist/llm/abortSignal.js +2 -3
  208. package/dist/llm/abortSignal.js.map +1 -1
  209. package/dist/llm/factory.d.ts +29 -25
  210. package/dist/llm/factory.d.ts.map +1 -1
  211. package/dist/llm/factory.js +34 -69
  212. package/dist/llm/factory.js.map +1 -1
  213. package/dist/llm/openaiCompatible.d.ts +25 -40
  214. package/dist/llm/openaiCompatible.d.ts.map +1 -1
  215. package/dist/llm/openaiCompatible.js +181 -129
  216. package/dist/llm/openaiCompatible.js.map +1 -1
  217. package/dist/llm/provider.d.ts +29 -42
  218. package/dist/llm/provider.d.ts.map +1 -1
  219. package/dist/llm/provider.js +11 -10
  220. package/dist/llm/provider.js.map +1 -1
  221. package/dist/llm/types.d.ts +54 -11
  222. package/dist/llm/types.d.ts.map +1 -1
  223. package/dist/llm/types.js +0 -5
  224. package/dist/llm/types.js.map +1 -1
  225. package/dist/logging/logger.d.ts +8 -29
  226. package/dist/logging/logger.d.ts.map +1 -1
  227. package/dist/logging/logger.js +43 -233
  228. package/dist/logging/logger.js.map +1 -1
  229. package/dist/logging/loggerInterface.d.ts +9 -8
  230. package/dist/logging/loggerInterface.d.ts.map +1 -1
  231. package/dist/memory/gcService.d.ts +164 -0
  232. package/dist/memory/gcService.d.ts.map +1 -0
  233. package/dist/memory/gcService.js +215 -0
  234. package/dist/memory/gcService.js.map +1 -0
  235. package/dist/memory/governance.d.ts +17 -0
  236. package/dist/memory/governance.d.ts.map +1 -0
  237. package/dist/memory/governance.js +17 -0
  238. package/dist/memory/governance.js.map +1 -0
  239. package/dist/memory/inMemoryRoundStore.d.ts +124 -0
  240. package/dist/memory/inMemoryRoundStore.d.ts.map +1 -0
  241. package/dist/memory/inMemoryRoundStore.js +216 -0
  242. package/dist/memory/inMemoryRoundStore.js.map +1 -0
  243. package/dist/memory/inMemorySessionStore.d.ts +92 -0
  244. package/dist/memory/inMemorySessionStore.d.ts.map +1 -0
  245. package/dist/memory/inMemorySessionStore.js +219 -0
  246. package/dist/memory/inMemorySessionStore.js.map +1 -0
  247. package/dist/memory/inMemorySessionViewLoader.d.ts +89 -0
  248. package/dist/memory/inMemorySessionViewLoader.d.ts.map +1 -0
  249. package/dist/memory/inMemorySessionViewLoader.js +183 -0
  250. package/dist/memory/inMemorySessionViewLoader.js.map +1 -0
  251. package/dist/memory/inMemoryStorage.d.ts +26 -141
  252. package/dist/memory/inMemoryStorage.d.ts.map +1 -1
  253. package/dist/memory/inMemoryStorage.js +48 -187
  254. package/dist/memory/inMemoryStorage.js.map +1 -1
  255. package/dist/memory/keywordsTouch.d.ts +20 -0
  256. package/dist/memory/keywordsTouch.d.ts.map +1 -0
  257. package/dist/memory/keywordsTouch.js +25 -0
  258. package/dist/memory/keywordsTouch.js.map +1 -0
  259. package/dist/memory/lockManager.d.ts +7 -2
  260. package/dist/memory/lockManager.d.ts.map +1 -1
  261. package/dist/memory/lockManager.js +35 -11
  262. package/dist/memory/lockManager.js.map +1 -1
  263. package/dist/memory/projectManager.d.ts +30 -128
  264. package/dist/memory/projectManager.d.ts.map +1 -1
  265. package/dist/memory/projectManager.js +39 -171
  266. package/dist/memory/projectManager.js.map +1 -1
  267. package/dist/memory/projectRegistry.d.ts +22 -37
  268. package/dist/memory/projectRegistry.d.ts.map +1 -1
  269. package/dist/memory/projectRegistry.js +78 -85
  270. package/dist/memory/projectRegistry.js.map +1 -1
  271. package/dist/memory/roundStore.d.ts +629 -0
  272. package/dist/memory/roundStore.d.ts.map +1 -0
  273. package/dist/memory/roundStore.js +116 -0
  274. package/dist/memory/roundStore.js.map +1 -0
  275. package/dist/memory/sessionStore.d.ts +70 -61
  276. package/dist/memory/sessionStore.d.ts.map +1 -1
  277. package/dist/memory/sessionStore.js +23 -1
  278. package/dist/memory/sessionStore.js.map +1 -1
  279. package/dist/memory/sessionViewLoader.d.ts +141 -0
  280. package/dist/memory/sessionViewLoader.d.ts.map +1 -0
  281. package/dist/memory/sessionViewLoader.js +65 -0
  282. package/dist/memory/sessionViewLoader.js.map +1 -0
  283. package/dist/memory/sourceValidation.d.ts +18 -9
  284. package/dist/memory/sourceValidation.d.ts.map +1 -1
  285. package/dist/memory/sourceValidation.js +35 -29
  286. package/dist/memory/sourceValidation.js.map +1 -1
  287. package/dist/memory/storageInterface.d.ts +45 -126
  288. package/dist/memory/storageInterface.d.ts.map +1 -1
  289. package/dist/memory/types.d.ts +82 -168
  290. package/dist/memory/types.d.ts.map +1 -1
  291. package/dist/memory/types.js +116 -79
  292. package/dist/memory/types.js.map +1 -1
  293. package/dist/project-search/projectSearchProvider.d.ts +29 -0
  294. package/dist/project-search/projectSearchProvider.d.ts.map +1 -0
  295. package/dist/project-search/projectSearchProvider.js +57 -0
  296. package/dist/project-search/projectSearchProvider.js.map +1 -0
  297. package/dist/project-search/terms.d.ts +14 -0
  298. package/dist/project-search/terms.d.ts.map +1 -0
  299. package/dist/project-search/terms.js +68 -0
  300. package/dist/project-search/terms.js.map +1 -0
  301. package/dist/project-search/types.d.ts +139 -0
  302. package/dist/project-search/types.d.ts.map +1 -0
  303. package/dist/project-search/types.js +8 -0
  304. package/dist/project-search/types.js.map +1 -0
  305. package/dist/role-pack/capabilityMap.d.ts +28 -0
  306. package/dist/role-pack/capabilityMap.d.ts.map +1 -0
  307. package/dist/role-pack/capabilityMap.js +56 -0
  308. package/dist/role-pack/capabilityMap.js.map +1 -0
  309. package/dist/role-pack/constants.d.ts +21 -0
  310. package/dist/role-pack/constants.d.ts.map +1 -0
  311. package/dist/role-pack/constants.js +21 -0
  312. package/dist/role-pack/constants.js.map +1 -0
  313. package/dist/role-pack/rolePackManager.d.ts +269 -0
  314. package/dist/role-pack/rolePackManager.d.ts.map +1 -0
  315. package/dist/role-pack/rolePackManager.js +1082 -0
  316. package/dist/role-pack/rolePackManager.js.map +1 -0
  317. package/dist/role-pack/strategyKeys.d.ts +100 -0
  318. package/dist/role-pack/strategyKeys.d.ts.map +1 -0
  319. package/dist/role-pack/strategyKeys.js +184 -0
  320. package/dist/role-pack/strategyKeys.js.map +1 -0
  321. package/dist/role-pack/strategyResolver.d.ts +109 -0
  322. package/dist/role-pack/strategyResolver.d.ts.map +1 -0
  323. package/dist/role-pack/strategyResolver.js +304 -0
  324. package/dist/role-pack/strategyResolver.js.map +1 -0
  325. package/dist/role-pack/types.d.ts +237 -0
  326. package/dist/role-pack/types.d.ts.map +1 -0
  327. package/dist/role-pack/types.js +8 -0
  328. package/dist/role-pack/types.js.map +1 -0
  329. package/dist/role-pack/validator.d.ts +38 -0
  330. package/dist/role-pack/validator.d.ts.map +1 -0
  331. package/dist/role-pack/validator.js +436 -0
  332. package/dist/role-pack/validator.js.map +1 -0
  333. package/dist/security/pathGuard.d.ts +69 -72
  334. package/dist/security/pathGuard.d.ts.map +1 -1
  335. package/dist/security/pathGuard.js +151 -131
  336. package/dist/security/pathGuard.js.map +1 -1
  337. package/dist/skill/skillLayer3.d.ts +91 -0
  338. package/dist/skill/skillLayer3.d.ts.map +1 -0
  339. package/dist/skill/skillLayer3.js +104 -0
  340. package/dist/skill/skillLayer3.js.map +1 -0
  341. package/dist/skill/skillManager.d.ts +127 -56
  342. package/dist/skill/skillManager.d.ts.map +1 -1
  343. package/dist/skill/skillManager.js +318 -163
  344. package/dist/skill/skillManager.js.map +1 -1
  345. package/dist/skill/skillScriptRunner.d.ts +97 -0
  346. package/dist/skill/skillScriptRunner.d.ts.map +1 -0
  347. package/dist/skill/skillScriptRunner.js +271 -0
  348. package/dist/skill/skillScriptRunner.js.map +1 -0
  349. package/dist/skill/types.d.ts +73 -17
  350. package/dist/skill/types.d.ts.map +1 -1
  351. package/dist/skill/types.js +5 -1
  352. package/dist/skill/types.js.map +1 -1
  353. package/dist/utils/array.d.ts +5 -6
  354. package/dist/utils/array.d.ts.map +1 -1
  355. package/dist/utils/array.js +6 -6
  356. package/dist/utils/array.js.map +1 -1
  357. package/dist/utils/atomicWrite.d.ts +8 -0
  358. package/dist/utils/atomicWrite.d.ts.map +1 -0
  359. package/dist/utils/atomicWrite.js +31 -0
  360. package/dist/utils/atomicWrite.js.map +1 -0
  361. package/dist/utils/backgroundTask.d.ts +38 -0
  362. package/dist/utils/backgroundTask.d.ts.map +1 -0
  363. package/dist/utils/backgroundTask.js +117 -0
  364. package/dist/utils/backgroundTask.js.map +1 -0
  365. package/dist/utils/configResourceManager.d.ts +79 -0
  366. package/dist/utils/configResourceManager.d.ts.map +1 -0
  367. package/dist/utils/configResourceManager.js +150 -0
  368. package/dist/utils/configResourceManager.js.map +1 -0
  369. package/dist/utils/errors.d.ts +48 -56
  370. package/dist/utils/errors.d.ts.map +1 -1
  371. package/dist/utils/errors.js +60 -58
  372. package/dist/utils/errors.js.map +1 -1
  373. package/dist/utils/eventEmitter.d.ts +141 -63
  374. package/dist/utils/eventEmitter.d.ts.map +1 -1
  375. package/dist/utils/eventEmitter.js +50 -35
  376. package/dist/utils/eventEmitter.js.map +1 -1
  377. package/dist/utils/fileSafe.d.ts +20 -0
  378. package/dist/utils/fileSafe.d.ts.map +1 -0
  379. package/dist/utils/fileSafe.js +56 -0
  380. package/dist/utils/fileSafe.js.map +1 -0
  381. package/dist/utils/frontmatter.d.ts +2 -3
  382. package/dist/utils/frontmatter.d.ts.map +1 -1
  383. package/dist/utils/frontmatter.js +6 -5
  384. package/dist/utils/frontmatter.js.map +1 -1
  385. package/dist/utils/hash.d.ts +12 -0
  386. package/dist/utils/hash.d.ts.map +1 -0
  387. package/dist/utils/hash.js +27 -0
  388. package/dist/utils/hash.js.map +1 -0
  389. package/dist/utils/http.d.ts +17 -0
  390. package/dist/utils/http.d.ts.map +1 -0
  391. package/dist/utils/http.js +29 -0
  392. package/dist/utils/http.js.map +1 -0
  393. package/dist/utils/json.d.ts +1 -1
  394. package/dist/utils/json.js +1 -1
  395. package/dist/utils/math.d.ts +34 -1
  396. package/dist/utils/math.d.ts.map +1 -1
  397. package/dist/utils/math.js +47 -14
  398. package/dist/utils/math.js.map +1 -1
  399. package/dist/utils/objects.d.ts +2 -3
  400. package/dist/utils/objects.d.ts.map +1 -1
  401. package/dist/utils/objects.js +2 -3
  402. package/dist/utils/objects.js.map +1 -1
  403. package/dist/utils/recallDefaults.d.ts +16 -0
  404. package/dist/utils/recallDefaults.d.ts.map +1 -0
  405. package/dist/utils/recallDefaults.js +16 -0
  406. package/dist/utils/recallDefaults.js.map +1 -0
  407. package/dist/utils/safeTimer.d.ts +8 -36
  408. package/dist/utils/safeTimer.d.ts.map +1 -1
  409. package/dist/utils/safeTimer.js +9 -37
  410. package/dist/utils/safeTimer.js.map +1 -1
  411. package/dist/utils/scanner.d.ts +97 -17
  412. package/dist/utils/scanner.d.ts.map +1 -1
  413. package/dist/utils/scanner.js +269 -47
  414. package/dist/utils/scanner.js.map +1 -1
  415. package/dist/utils/segmenter.d.ts +20 -29
  416. package/dist/utils/segmenter.d.ts.map +1 -1
  417. package/dist/utils/segmenter.js +230 -88
  418. package/dist/utils/segmenter.js.map +1 -1
  419. package/dist/utils/strings.d.ts +15 -32
  420. package/dist/utils/strings.d.ts.map +1 -1
  421. package/dist/utils/strings.js +25 -44
  422. package/dist/utils/strings.js.map +1 -1
  423. package/dist/utils/time.d.ts +37 -0
  424. package/dist/utils/time.d.ts.map +1 -1
  425. package/dist/utils/time.js +56 -0
  426. package/dist/utils/time.js.map +1 -1
  427. package/dist/utils/toError.d.ts +13 -1
  428. package/dist/utils/toError.d.ts.map +1 -1
  429. package/dist/utils/toError.js +18 -1
  430. package/dist/utils/toError.js.map +1 -1
  431. package/dist/web-fetch/fetchWebFetchProvider.d.ts +14 -0
  432. package/dist/web-fetch/fetchWebFetchProvider.d.ts.map +1 -0
  433. package/dist/web-fetch/fetchWebFetchProvider.js +69 -0
  434. package/dist/web-fetch/fetchWebFetchProvider.js.map +1 -0
  435. package/dist/web-fetch/types.d.ts +30 -0
  436. package/dist/web-fetch/types.d.ts.map +1 -0
  437. package/dist/web-fetch/types.js +7 -0
  438. package/dist/web-fetch/types.js.map +1 -0
  439. package/dist/web-fetch/webFetchProvider.d.ts +10 -0
  440. package/dist/web-fetch/webFetchProvider.d.ts.map +1 -0
  441. package/dist/web-fetch/webFetchProvider.js +28 -0
  442. package/dist/web-fetch/webFetchProvider.js.map +1 -0
  443. package/dist/web-search/fetchWebSearchProvider.d.ts +27 -0
  444. package/dist/web-search/fetchWebSearchProvider.d.ts.map +1 -0
  445. package/dist/web-search/fetchWebSearchProvider.js +199 -0
  446. package/dist/web-search/fetchWebSearchProvider.js.map +1 -0
  447. package/dist/web-search/types.d.ts +46 -0
  448. package/dist/web-search/types.d.ts.map +1 -0
  449. package/dist/web-search/types.js +2 -0
  450. package/dist/{persona → web-search}/types.js.map +1 -1
  451. package/dist/web-search/webSearchProvider.d.ts +10 -0
  452. package/dist/web-search/webSearchProvider.d.ts.map +1 -0
  453. package/dist/web-search/webSearchProvider.js +30 -0
  454. package/dist/web-search/webSearchProvider.js.map +1 -0
  455. package/docs/architecture/role-pack-authoring-guide.md +243 -0
  456. package/docs/architecture/role-pack-spec.md +767 -0
  457. package/docs/memora-api-reference.md +1175 -0
  458. package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +843 -0
  459. package/docs/role-pack-/345/274/200/346/224/276/351/224/256/346/214/207/345/215/227.md +148 -0
  460. package/package.json +105 -83
  461. package/role-packs/README.md +41 -0
  462. package/role-packs/memora/345/212/251/346/211/213/manifest.json +12 -0
  463. package/role-packs/memora/345/212/251/346/211/213/persona.md +12 -0
  464. package/role-packs/memora/345/212/251/346/211/213/rules.md +4 -0
  465. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/manifest.json +44 -0
  466. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +46 -0
  467. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +15 -0
  468. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/character-sheet.md +34 -0
  469. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/core-extractor.md +37 -0
  470. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/craft-review.md +69 -0
  471. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/dialogue-craft.md +45 -0
  472. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +46 -0
  473. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/empathy-craft.md +79 -0
  474. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +29 -0
  475. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/hotspot-mapping.md +121 -0
  476. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/idea-lever.md +42 -0
  477. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/logline-craft.md +47 -0
  478. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/longform-guard.md +64 -0
  479. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/need-finder.md +40 -0
  480. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +46 -0
  481. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/pacing-hook.md +34 -0
  482. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/polish-method.md +113 -0
  483. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/pov-discipline.md +79 -0
  484. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/SKILL.md +112 -0
  485. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/scripts/init-novel-project.mjs +441 -0
  486. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/relationship-web.md +47 -0
  487. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/scene-craft.md +46 -0
  488. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +60 -0
  489. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-structure.md +36 -0
  490. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/style-weaver.md +109 -0
  491. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/three-layer-check.md +27 -0
  492. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/world-builder.md +41 -0
  493. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/manifest.json +48 -0
  494. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/persona.md +73 -0
  495. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/rules.md +19 -0
  496. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/api-doc-writer.md +40 -0
  497. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/doc-planner.md +42 -0
  498. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/nutrient-search.md +28 -0
  499. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/seed-finder.md +28 -0
  500. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/ssot-audit.md +34 -0
  501. package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/skills/style-guide.md +40 -0
  502. package/dist/agent/guardrail.d.ts +0 -47
  503. package/dist/agent/guardrail.d.ts.map +0 -1
  504. package/dist/agent/guardrail.js +0 -51
  505. package/dist/agent/guardrail.js.map +0 -1
  506. package/dist/agent/managers/autoConfigRefiner.d.ts +0 -39
  507. package/dist/agent/managers/autoConfigRefiner.d.ts.map +0 -1
  508. package/dist/agent/managers/autoConfigRefiner.js +0 -150
  509. package/dist/agent/managers/autoConfigRefiner.js.map +0 -1
  510. package/dist/agent/managers/configManager.d.ts +0 -125
  511. package/dist/agent/managers/configManager.d.ts.map +0 -1
  512. package/dist/agent/managers/configManager.js +0 -194
  513. package/dist/agent/managers/configManager.js.map +0 -1
  514. package/dist/agent/managers/insightExtractor.d.ts +0 -139
  515. package/dist/agent/managers/insightExtractor.d.ts.map +0 -1
  516. package/dist/agent/managers/insightExtractor.js +0 -401
  517. package/dist/agent/managers/insightExtractor.js.map +0 -1
  518. package/dist/agent/managers/memoryDecayScheduler.d.ts +0 -198
  519. package/dist/agent/managers/memoryDecayScheduler.d.ts.map +0 -1
  520. package/dist/agent/managers/memoryDecayScheduler.js +0 -349
  521. package/dist/agent/managers/memoryDecayScheduler.js.map +0 -1
  522. package/dist/agent/managers/relationBuilder.d.ts +0 -131
  523. package/dist/agent/managers/relationBuilder.d.ts.map +0 -1
  524. package/dist/agent/managers/relationBuilder.js +0 -192
  525. package/dist/agent/managers/relationBuilder.js.map +0 -1
  526. package/dist/agent/personaMatcher.d.ts +0 -29
  527. package/dist/agent/personaMatcher.d.ts.map +0 -1
  528. package/dist/agent/personaMatcher.js +0 -60
  529. package/dist/agent/personaMatcher.js.map +0 -1
  530. package/dist/agent/userFactExtractor.d.ts +0 -25
  531. package/dist/agent/userFactExtractor.d.ts.map +0 -1
  532. package/dist/agent/userFactExtractor.js +0 -81
  533. package/dist/agent/userFactExtractor.js.map +0 -1
  534. package/dist/eval/evalRunner.d.ts +0 -94
  535. package/dist/eval/evalRunner.d.ts.map +0 -1
  536. package/dist/eval/evalRunner.js +0 -141
  537. package/dist/eval/evalRunner.js.map +0 -1
  538. package/dist/eval/evalTypes.d.ts +0 -148
  539. package/dist/eval/evalTypes.d.ts.map +0 -1
  540. package/dist/eval/evalTypes.js +0 -118
  541. package/dist/eval/evalTypes.js.map +0 -1
  542. package/dist/eval/scenarios.d.ts +0 -33
  543. package/dist/eval/scenarios.d.ts.map +0 -1
  544. package/dist/eval/scenarios.js +0 -109
  545. package/dist/eval/scenarios.js.map +0 -1
  546. package/dist/llm/embedding.d.ts +0 -67
  547. package/dist/llm/embedding.d.ts.map +0 -1
  548. package/dist/llm/embedding.js +0 -184
  549. package/dist/llm/embedding.js.map +0 -1
  550. package/dist/memory/hybridMerge.d.ts +0 -54
  551. package/dist/memory/hybridMerge.d.ts.map +0 -1
  552. package/dist/memory/hybridMerge.js +0 -36
  553. package/dist/memory/hybridMerge.js.map +0 -1
  554. package/dist/memory/inMemoryRelationStore.d.ts +0 -51
  555. package/dist/memory/inMemoryRelationStore.d.ts.map +0 -1
  556. package/dist/memory/inMemoryRelationStore.js +0 -65
  557. package/dist/memory/inMemoryRelationStore.js.map +0 -1
  558. package/dist/memory/loader.d.ts +0 -49
  559. package/dist/memory/loader.d.ts.map +0 -1
  560. package/dist/memory/loader.js +0 -93
  561. package/dist/memory/loader.js.map +0 -1
  562. package/dist/memory/recall.d.ts +0 -66
  563. package/dist/memory/recall.d.ts.map +0 -1
  564. package/dist/memory/recall.js +0 -142
  565. package/dist/memory/recall.js.map +0 -1
  566. package/dist/memory/relationStore.d.ts +0 -78
  567. package/dist/memory/relationStore.d.ts.map +0 -1
  568. package/dist/memory/relationStore.js +0 -2
  569. package/dist/memory/relationStore.js.map +0 -1
  570. package/dist/memory/store.d.ts +0 -50
  571. package/dist/memory/store.d.ts.map +0 -1
  572. package/dist/memory/store.js +0 -161
  573. package/dist/memory/store.js.map +0 -1
  574. package/dist/memory/userProfile.d.ts +0 -156
  575. package/dist/memory/userProfile.d.ts.map +0 -1
  576. package/dist/memory/userProfile.js +0 -320
  577. package/dist/memory/userProfile.js.map +0 -1
  578. package/dist/memory/vectorStore.d.ts +0 -185
  579. package/dist/memory/vectorStore.d.ts.map +0 -1
  580. package/dist/memory/vectorStore.js +0 -257
  581. package/dist/memory/vectorStore.js.map +0 -1
  582. package/dist/persona/personaManager.d.ts +0 -160
  583. package/dist/persona/personaManager.d.ts.map +0 -1
  584. package/dist/persona/personaManager.js +0 -414
  585. package/dist/persona/personaManager.js.map +0 -1
  586. package/dist/persona/types.d.ts +0 -32
  587. package/dist/persona/types.d.ts.map +0 -1
  588. package/dist/persona/types.js +0 -5
@@ -1,13 +1,13 @@
1
1
  export type Permission = 'owner' | 'guest';
2
2
  export type WriteDecision = 'confirmed' | 'declined' | 'auto-approved' | 'auto-denied';
3
3
  export interface AuditEvent {
4
- /** 事件类型 */
4
+ /** 事件类型:路径允许/拒绝、写入确认/拒绝/自动 */
5
5
  type: 'path-allow' | 'path-deny' | 'write-confirm' | 'write-decline' | 'write-auto';
6
6
  /** 涉及的绝对路径 */
7
7
  path: string;
8
8
  /** 工具名(read_file / write_file / 自定义工具名) */
9
9
  tool?: string;
10
- /** 调用链来源(builtin / custom / system),标记安全检查的触发方 */
10
+ /** 调用链来源,标记安全检查的触发方 */
11
11
  source?: 'builtin' | 'custom' | 'system';
12
12
  /** 用户决策(写入二次确认场景) */
13
13
  decision?: WriteDecision;
@@ -16,19 +16,11 @@ export interface AuditEvent {
16
16
  /** 时间戳(ISO 8601) */
17
17
  timestamp: string;
18
18
  }
19
- /**
20
- * 审计日志订阅器
21
- * 默认输出到 pino logger;可被业务层重定向到独立审计文件
22
- */
19
+ /** 审计日志订阅器:默认经内核 logger 单例输出,可被业务层重定向到独立审计文件 */
23
20
  export type AuditListener = (event: AuditEvent) => void;
24
21
  /**
25
- * 写入确认请求
26
- *
27
- * 宿主程序在非交互式环境(WebUI/桌宠/无终端服务)需要自定义确认 UI。
28
- * 注入此回调后,SecurityGuard.requestWriteConfirmation() 会调用它而不是直接读 stdin。
29
- *
30
- * 返回 true 确认写入,false 拒绝写入。
31
- * 抛错视为拒绝(fail-closed,安全优先)。
22
+ * 写入确认请求:宿主在非交互式环境(WebUI/桌宠/无终端)注入自定义确认 UI,
23
+ * 走此回调而非直接读 stdin。返回 true 确认 / false 拒绝;抛错视为拒绝(fail-closed)。
32
24
  */
33
25
  export type WriteConfirmationRequest = (info: WriteConfirmationInfo) => Promise<boolean>;
34
26
  /** 写入确认请求的载荷 */
@@ -37,107 +29,112 @@ export interface WriteConfirmationInfo {
37
29
  targetPath: string;
38
30
  /** 工具名(如 write_file) */
39
31
  tool: string;
40
- /** 人类可读的描述("写入 100 字符到 foo.md") */
32
+ /** 人类可读描述("写入 100 字符到 foo.md") */
41
33
  description?: string;
42
34
  /** 权限模式(owner / guest) */
43
35
  permission: Permission;
44
- /** 是否需要确认(owner + confirmWrites=false 时为 false,宿主可跳过弹窗) */
36
+ /** 是否需确认(owner+confirmWrites=false 时为 false,宿主可跳过弹窗) */
45
37
  needsConfirm: boolean;
46
- /** 文件当前内容预览(截断到 10KB,null 表示新文件)—— 供宿主 UI 展示 diff */
38
+ /** 文件当前内容预览(截断到 10KB,null 表示新文件)——供宿主 UI 展示 diff */
47
39
  beforeContent?: string | null;
48
- /** 写入后内容预览(截断到 10KB)—— 供宿主 UI 展示 diff */
40
+ /** 写入后内容预览(截断到 10KB)——供宿主 UI 展示 diff */
49
41
  afterContent?: string;
50
42
  }
43
+ /** diff 内容最大长度(10KB),防大文件撑爆 IPC 传输和 UI 渲染。宿主 UI 展示上限从本常量 import 对齐(唯一真源) */
44
+ export declare const MAX_DIFF_CONTENT_LENGTH = 10240;
51
45
  export declare class SecurityGuard {
52
- /** owner 是否启用写入二次确认;guest 强制开启 */
53
- readonly confirmWrites: boolean;
54
46
  /** 权限模式 */
55
47
  readonly permission: Permission;
56
48
  private readonly listeners;
57
- /** 审计事件缓冲(最近 N 条,供调试与回溯) */
58
- private readonly auditBuffer;
59
- private readonly bufferLimit;
60
49
  /**
61
- * 注入式写入确认回调。
62
- * 宿主注册后,requestWriteConfirmation() 走自定义 UI;
63
- * 不注册时回退到终端 readline(CLI 场景)。
50
+ * 注入式写入确认回调:宿主注册后走自定义 UI;不注册时回退到终端 readline(CLI 场景)。
64
51
  */
65
52
  private confirmationHandler;
66
- /** 允许访问的根目录列表(白名单) */
67
- private readonly allowedRoots;
68
- constructor(projectPath: string, memoraDir: string, extraAllowedPaths?: string[],
69
- /** owner 是否启用写入二次确认;guest 强制开启 */
70
- confirmWrites?: boolean,
53
+ /** 基准信任根(projectPath/memoraDir/configDir/agentDataDir,构造器固化,运行时不可移除) */
54
+ private readonly baseRoots;
55
+ /** 用户额外白名单(运行时经 setAllowedPaths 热更新) */
56
+ private extraRoots;
57
+ /** 允许访问的根目录列表(白名单)= baseRoots + extraRoots(派生,断言时遍历) */
58
+ private allowedRoots;
59
+ /** owner 是否启用写入二次确认;guest 强制开启(可运行时切换) */
60
+ confirmWrites: boolean;
61
+ /** 是否对脚本/代码执行启用确认(owner 模式;guest 强制开启;默认 false = 默认不弹窗) */
62
+ confirmScripts: boolean;
63
+ constructor(projectPath: string, memoraDir: string, extraAllowedPaths?: string[], confirmWrites?: boolean,
71
64
  /** 权限模式 */
72
65
  permission?: Permission,
66
+ /** 脚本执行确认开关(独立于写入确认,供对 run_code/run_project_script 单独收紧) */
67
+ confirmScripts?: boolean,
73
68
  /** Agent 级配置目录(personas/rules/skills 所在目录) */
74
69
  configDir?: string,
75
- /** Agent 级数据目录(memora.db/vectors 所在目录) */
70
+ /** Agent 级数据目录(宿主传入;内核不假设其下的文件形态) */
76
71
  agentDataDir?: string);
72
+ /** 注册自定义写入确认回调(宿主接入);取消注册传入 null。WebUI/桌宠等无终端场景走此回调而非读 stdin */
73
+ onWriteConfirmation(handler: WriteConfirmationRequest | null): void;
77
74
  /**
78
- * 注册自定义写入确认回调(宿主程序接入)
79
- *
80
- * 适用于 WebUI/桌宠/无终端服务。注册后,requestWriteConfirmation()
81
- * 不再直接读 stdin,而是回调此函数让宿主决定如何提示用户。
82
- *
83
- * 取消注册:传入 null。
75
+ * 运行时切换写入二次确认开关(宿主设置面板热更新)
84
76
  *
85
- * @example
86
- * securityGuard.onWriteConfirmation(async (info) => {
87
- * return await showConfirmDialog(info.targetPath, info.description);
88
- * });
77
+ * 开启后:owner 模式下写文件前会触发 confirmationHandler 弹窗审批;
78
+ * 关闭后:owner 模式下写文件自动批准(审计仍会记录)。
79
+ * guest 模式不受影响——始终需要确认。
89
80
  */
90
- onWriteConfirmation(handler: WriteConfirmationRequest | null): void;
81
+ setConfirmWrites(value: boolean): void;
91
82
  /**
92
- * 订阅审计事件
93
- * @returns 取消订阅函数
83
+ * 运行时切换脚本/代码执行确认开关(宿主设置面板热更新)
84
+ *
85
+ * 开启后:owner 模式下 run_code/run_project_script 执行前会触发 confirmationHandler 弹窗审批;
86
+ * 关闭后:owner 模式下脚本自动批准(审计仍会记录)。
87
+ * guest 模式不受影响——脚本执行始终需要确认。
94
88
  */
95
- onAudit(listener: AuditListener): () => void;
89
+ setConfirmScripts(value: boolean): void;
96
90
  /**
97
- * 获取最近的审计事件(深拷贝,外部不可修改内部缓冲)
91
+ * 运行时设置「用户额外白名单」(宿主设置面板热更新)
92
+ *
93
+ * 仅操作额外项(extraRoots),基准信任根(baseRoots)永不被触碰——守住安全显式性:
94
+ * 项目目录、memora 数据目录、配置/数据目录始终允许访问,用户无法误删。
95
+ * 传空数组 = 清空额外项(仅留基准根,等价「重置」)。
96
+ * 黑名单(BLOCKED_PATTERNS)对新增路径仍强制生效——白名单是允许列表,非绕过黑名单的通行证。
98
97
  */
99
- getRecentAudits(limit?: number): AuditEvent[];
98
+ setAllowedPaths(extraPaths: string[]): void;
99
+ /** 订阅审计事件;@returns 取消订阅函数 */
100
+ onAudit(listener: AuditListener): () => void;
100
101
  /**
101
- * 断言路径允许访问
102
- * @throws Error 不在白名单时
103
- * @param source 调用链来源标记
102
+ * 断言路径允许访问(命中即拒绝);黑名单优先,其次白名单前缀匹配(追加 sep 防兄弟目录绕过)。
103
+ * @throws 不在白名单时
104
104
  */
105
105
  assertPathAllowed(absolutePath: string, tool?: string, source?: 'builtin' | 'custom' | 'system'): void;
106
106
  /**
107
- * 写入操作前请求用户确认
108
- *
109
- * 规则:
110
- * - guest 模式:始终要求确认
111
- * - owner + confirmWrites=true:要求确认
112
- * - owner + confirmWrites=false:自动批准
113
- *
114
- * 决策(fail-closed):
115
- * - 需要确认时,必须通过 onWriteConfirmation() 注入 confirmationHandler
116
- * - 未注入 handler 时,**直接拒绝写入**(返回 false)
117
- * - 理由:内核纯逻辑库不应依赖交互式终端 I/O;宿主程序负责提供确认 UI
118
- * - 安全优先:未配置 = 拒绝,避免无意识放行
119
- *
120
- * @returns true 确认通过;false 用户拒绝或未注入 handler(fail-closed)
107
+ * 写入前请求用户确认。guest 或 confirmWrites 需确认;未注入 confirmationHandler 时 fail-closed 拒绝(返回 false),
108
+ * 理由:内核纯逻辑库不依赖交互式终端 I/O,宿主负责确认 UI;安全优先:未配置 = 拒绝。
121
109
  */
122
110
  requestWriteConfirmation(targetPath: string, tool: string, description?: string,
123
- /** diff 内容选项(供宿主 UI 展示变更预览,自动截断到 10KB) */
111
+ /** diff 内容选项(宿主 UI 变更预览用,自动截断到 10KB) */
124
112
  options?: {
125
113
  beforeContent?: string | null;
126
114
  afterContent?: string;
127
115
  }): Promise<boolean>;
128
116
  /**
129
- * 通过宿主注入的 confirmationHandler 进行写入确认
117
+ * 脚本/代码执行前确认(run_code / run_project_script 的执行闸)
130
118
  *
131
- * 从 requestWriteConfirmation 拆分。抛错视为拒绝(fail-closed 安全优先)。
132
- * 此方法是唯一的确认执行路径。
119
+ * 判据与写入确认同构:guest 模式或 confirmScripts 需确认;未注入 confirmationHandler 时
120
+ * fail-closed 拒绝。owner + confirmScripts=false 自动批准(默认),审计仍记录。
121
+ * target 为脚本绝对路径(run_project_script)或描述型标识(run_code 内联代码无落盘路径)。
122
+ */
123
+ confirmScriptRun(targetPath: string, tool: string, description?: string): Promise<boolean>;
124
+ /**
125
+ * 确认闸公共核心(SSOT:写入确认与脚本执行确认的唯一执行路径)
133
126
  *
134
- * @param info 确认信息(含 diff 内容)
135
- * @returns true 确认通过;false 用户拒绝或回调异常
127
+ * needConfirm=false → 自动批准(审计 write-auto);为 true 且未注入 confirmationHandler
128
+ * → fail-closed 拒绝(审计 write-decline);否则经 confirmViaHandler 走宿主确认 UI。
129
+ * diff 仅写入场景有,脚本执行不传(域留空)。
136
130
  */
137
- private confirmViaHandler;
131
+ private confirmGate;
138
132
  /**
139
- * 触发审计事件 + 写入日志 + 通知订阅者
133
+ * 通过宿主注入的 confirmationHandler 执行写入确认(唯一确认执行路径)。
134
+ * 抛错视为拒绝(fail-closed 安全优先)。
140
135
  */
136
+ private confirmViaHandler;
137
+ /** 触发审计事件:写日志 + 通知订阅者 */
141
138
  private emitAudit;
142
139
  }
143
140
  //# sourceMappingURL=pathGuard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"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"}
@@ -1,32 +1,20 @@
1
1
  /**
2
2
  * 路径白名单 + 审计日志
3
- *
4
- * 4 类允许根 + 28 类禁止规则
5
- * 详见 ADR-006 · 安全模型
6
- *
7
- * 写入二次确认 + 审计日志:未注入 confirmationHandler 时 fail-closed 拒绝写入。
8
- * 内核纯逻辑库不应依赖交互式终端 I/O(node:readline/promises + node:process),
9
- * 宿主程序应通过 onWriteConfirmation() 注入自己的确认 UI(Electron/Web/CLI 各自实现)。
3
+ * 4 类允许根 + 28 类禁止规则。
4
+ * 写入需二次确认 + 审计日志:未注入 confirmationHandler 时 fail-closed 拒绝写入。
5
+ * 内核纯逻辑库不依赖交互式终端 I/O,宿主应通过 onWriteConfirmation() 注入自己的确认 UI。
10
6
  */
11
7
  import { resolve, sep, dirname, basename, join } from 'node:path';
12
8
  import { realpathSync } from 'node:fs';
13
9
  import { logger } from '../logging/logger.js';
14
- import { securityError, toError } from '../utils/errors.js';
10
+ import { securityError } from '../utils/errors.js';
11
+ import { toError } from '../utils/toError.js';
15
12
  import { expandHome } from '../utils/path.js';
16
13
  import { nowIso } from '../utils/time.js';
17
14
  /**
18
- * 解析路径的真实绝对路径(解析符号链接链)
19
- *
20
- * 安全考量:若不解析符号链接,攻击者可在项目内放置指向 /etc 的符号链接,
21
- * 绕过白名单前缀匹配访问任意系统目录(P0 符号链接逃逸漏洞)。
22
- *
23
- * 策略:
24
- * - 路径存在时:realpathSync 解析完整符号链接链
25
- * - 路径不存在时(写入新文件场景):逐级向上查找已存在的父目录并 realpath,再拼接不存在部分
26
- * - 全程不存在时:回退到 resolve()(白名单/黑名单仍会兜底校验)
27
- *
28
- * @param p 任意路径(相对或绝对)
29
- * @returns 解析符号链接后的真实绝对路径
15
+ * 解析符号链接后的真实绝对路径。
16
+ * 安全考量:不解析符号链接时,攻击者可用项目内指向 /etc 的符号链接绕过白名单前缀匹配访问任意系统目录(路径穿越逃逸)。
17
+ * 不存在时(写新文件)逐级向上解析已存在父目录再拼接;全程不存在时回退 resolve()(白名单/黑名单仍兜底校验)。
30
18
  */
31
19
  function resolveRealpath(p) {
32
20
  const resolved = resolve(p);
@@ -34,7 +22,7 @@ function resolveRealpath(p) {
34
22
  return realpathSync(resolved);
35
23
  }
36
24
  catch {
37
- // 路径不存在 - 递归解析已存在的父目录
25
+ // 路径不存在:递归解析已存在的父目录
38
26
  const parent = dirname(resolved);
39
27
  const base = basename(resolved);
40
28
  try {
@@ -42,123 +30,159 @@ function resolveRealpath(p) {
42
30
  return join(realParent, base);
43
31
  }
44
32
  catch {
45
- // 父目录也不存在 - 继续向上递归
33
+ // 父目录也不存在:继续向上递归
46
34
  const realGrandParent = resolveRealpath(parent);
47
35
  return join(realGrandParent, base);
48
36
  }
49
37
  }
50
38
  }
51
39
  const BLOCKED_PATTERNS = [
52
- // ─── 系统凭证文件(跨平台,路径段匹配)───
40
+ // 系统凭证文件(跨平台,路径段匹配)
53
41
  /(^|[\\/])\.ssh([\\/]|$)/i,
54
42
  /(^|[\\/])\.gnupg([\\/]|$)/i,
55
43
  /(^|[\\/])\.netrc$/i,
56
44
  /(^|[\\/])\.pgpass$/i,
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, // 用户密码哈希
45
+ // 包管理器凭证:多为明文存储,可含推发令牌
46
+ /(^|[\\/])\.gitconfig$/i,
47
+ /(^|[\\/])\.git-credentials$/i,
48
+ /(^|[\\/])\.npmrc$/i,
49
+ /(^|[\\/])\.pypirc$/i,
50
+ /(^|[\\/])\.gem[\\/]credentials$/i,
51
+ /(^|[\\/])\.composer[\\/]auth\.json$/i,
52
+ /(^|[\\/])\.htpasswd$/i,
53
+ // Linux/macOS 系统账户文件
54
+ /[\\/]etc[\\/]passwd/i,
67
55
  /[\\/]etc[\\/]shadow/i,
68
- /[\\/]etc[\\/]gshadow/i, // 组密码哈希
69
- /[\\/]etc[\\/]sudoers/i, // sudo 配置
70
- // ─── 云服务凭证 ───
56
+ /[\\/]etc[\\/]gshadow/i,
57
+ /[\\/]etc[\\/]sudoers/i,
58
+ // 云服务与容器凭证
71
59
  /(^|[\\/])\.aws([\\/]|$)/i,
72
60
  /(^|[\\/])\.azure([\\/]|$)/i,
73
61
  /(^|[\\/])\.docker([\\/]|$)/i,
74
62
  /(^|[\\/])\.kube([\\/]|$)/i,
75
- /(^|[\\/])\.config[\\/]gcloud([\\/]|$)/i, // gcloud 配置(加 .config 前缀边界,避免误拦用户 gcloud-tools 目录)
76
- // ─── 环境变量文件(.env / .env.local / .env.production.local 等多段后缀)───
63
+ /(^|[\\/])\.config[\\/]gcloud([\\/]|$)/i,
64
+ // 环境变量文件(.env / .env.local / .env.production.local 等多段后缀;.envrc 独立于 .env.* 后缀模式)
77
65
  /(^|[\\/])\.env(\.[^\\/]+)?$/i,
78
- // .envrc(direnv 配置,可含环境变量和密钥,独立于 .env.* 后缀模式)
79
66
  /(^|[\\/])\.envrc$/i,
80
- // ─── Windows 系统目录 ───
81
- /[\\/]Windows([\\/]|$)/i, // C:\Windows(含 System、System32 等子目录)
82
- /[\\/]Program Files([\\/]|$)/i, // C:\Program Files
83
- /[\\/]Program Files \(x86\)([\\/]|$)/i, // C:\Program Files (x86)
84
- /[\\/]ProgramData([\\/]|$)/i, // C:\ProgramData(系统级应用数据)
85
- // ─── Linux/macOS 系统目录(根目录锚定 ^/,避免误伤项目内同名目录)───
67
+ // Windows 系统目录
68
+ /[\\/]Windows([\\/]|$)/i,
69
+ /[\\/]Program Files([\\/]|$)/i,
70
+ /[\\/]Program Files \(x86\)([\\/]|$)/i,
71
+ /[\\/]ProgramData([\\/]|$)/i,
72
+ // Linux/macOS 系统目录(根目录锚定 ^/,避免误伤项目内同名目录)
86
73
  /^\/(etc|usr|bin|sbin|var|root|home|lib|lib64|opt)([\\/]|$)/i,
87
- // ─── Linux/macOS 虚拟文件系统 + 启动目录(根目录锚定)───
74
+ // 虚拟文件系统 + 启动目录(根目录锚定)
88
75
  /^\/(proc|sys|boot)([\\/]|$)/i,
89
76
  ];
90
- /** diff 内容最大长度(10KB),防止大文件内容撑爆 IPC 传输和 UI 渲染 */
91
- const MAX_DIFF_CONTENT_LENGTH = 10240;
77
+ /** 运行时动态白名单(setAllowedPaths)最大条数,与 config/loader.ts 同值,防白名单膨胀 */
78
+ const MAX_EXTRA_ALLOWED_PATHS = 50;
79
+ /** diff 内容最大长度(10KB),防大文件撑爆 IPC 传输和 UI 渲染。宿主 UI 展示上限从本常量 import 对齐(唯一真源) */
80
+ export const MAX_DIFF_CONTENT_LENGTH = 10240;
92
81
  function truncateForDiff(content) {
93
82
  if (content === null || content === undefined)
94
83
  return content;
95
84
  if (content.length <= MAX_DIFF_CONTENT_LENGTH)
96
85
  return content;
97
- // 超过上限时截断并追加标记,让用户知道内容被裁剪
86
+ // 超限截断并追加标记,让用户知道内容被裁剪
98
87
  return content.slice(0, MAX_DIFF_CONTENT_LENGTH) + `\n...(已截断,共 ${content.length} 字符)`;
99
88
  }
100
89
  export class SecurityGuard {
101
- confirmWrites;
102
90
  permission;
103
91
  listeners = [];
104
- /** 审计事件缓冲(最近 N 条,供调试与回溯) */
105
- auditBuffer = [];
106
- bufferLimit = 100;
107
92
  /**
108
- * 注入式写入确认回调。
109
- * 宿主注册后,requestWriteConfirmation() 走自定义 UI;
110
- * 不注册时回退到终端 readline(CLI 场景)。
93
+ * 注入式写入确认回调:宿主注册后走自定义 UI;不注册时回退到终端 readline(CLI 场景)。
111
94
  */
112
95
  confirmationHandler = null;
113
- /** 允许访问的根目录列表(白名单) */
96
+ /** 基准信任根(projectPath/memoraDir/configDir/agentDataDir,构造器固化,运行时不可移除) */
97
+ baseRoots;
98
+ /** 用户额外白名单(运行时经 setAllowedPaths 热更新) */
99
+ extraRoots;
100
+ /** 允许访问的根目录列表(白名单)= baseRoots + extraRoots(派生,断言时遍历) */
114
101
  allowedRoots;
115
- constructor(projectPath, memoraDir, extraAllowedPaths = [],
116
- /** owner 是否启用写入二次确认;guest 强制开启 */
117
- confirmWrites = false,
102
+ /** owner 是否启用写入二次确认;guest 强制开启(可运行时切换) */
103
+ confirmWrites;
104
+ /** 是否对脚本/代码执行启用确认(owner 模式;guest 强制开启;默认 false = 默认不弹窗) */
105
+ confirmScripts;
106
+ constructor(projectPath, memoraDir, extraAllowedPaths = [], confirmWrites = false,
118
107
  /** 权限模式 */
119
108
  permission = 'owner',
109
+ /** 脚本执行确认开关(独立于写入确认,供对 run_code/run_project_script 单独收紧) */
110
+ confirmScripts = false,
120
111
  /** Agent 级配置目录(personas/rules/skills 所在目录) */
121
112
  configDir,
122
- /** Agent 级数据目录(memora.db/vectors 所在目录) */
113
+ /** Agent 级数据目录(宿主传入;内核不假设其下的文件形态) */
123
114
  agentDataDir) {
124
- this.confirmWrites = confirmWrites;
125
115
  this.permission = permission;
126
- // 构建白名单根目录列表:使用 resolveRealpath 解析符号链接,
127
- // 确保白名单基准是真实路径,与 assertPathAllowed 中的 resolveRealpath 对齐
128
- this.allowedRoots = [
116
+ // 基准信任根用真实路径(resolveRealpath),与 assertPathAllowed 对齐,避免前缀匹配错位
117
+ this.baseRoots = [
129
118
  resolveRealpath(expandHome(projectPath)),
130
119
  resolveRealpath(expandHome(memoraDir)),
131
120
  ];
132
121
  if (configDir) {
133
- this.allowedRoots.push(resolveRealpath(expandHome(configDir)));
122
+ this.baseRoots.push(resolveRealpath(expandHome(configDir)));
134
123
  }
135
124
  if (agentDataDir) {
136
- this.allowedRoots.push(resolveRealpath(expandHome(agentDataDir)));
137
- }
138
- for (const p of extraAllowedPaths) {
139
- this.allowedRoots.push(resolveRealpath(expandHome(p)));
125
+ this.baseRoots.push(resolveRealpath(expandHome(agentDataDir)));
140
126
  }
127
+ this.confirmWrites = confirmWrites;
128
+ // 脚本执行确认开关(独立于写入确认)
129
+ this.confirmScripts = confirmScripts;
130
+ // 用户额外白名单(构造器注入),基准根与额外项分离以便 setAllowedPaths 仅改额外项
131
+ this.extraRoots = extraAllowedPaths.map((p) => resolveRealpath(expandHome(p)));
132
+ this.allowedRoots = [...this.baseRoots, ...this.extraRoots];
133
+ }
134
+ /** 注册自定义写入确认回调(宿主接入);取消注册传入 null。WebUI/桌宠等无终端场景走此回调而非读 stdin */
135
+ onWriteConfirmation(handler) {
136
+ this.confirmationHandler = handler;
141
137
  }
142
138
  /**
143
- * 注册自定义写入确认回调(宿主程序接入)
144
- *
145
- * 适用于 WebUI/桌宠/无终端服务。注册后,requestWriteConfirmation()
146
- * 不再直接读 stdin,而是回调此函数让宿主决定如何提示用户。
139
+ * 运行时切换写入二次确认开关(宿主设置面板热更新)
147
140
  *
148
- * 取消注册:传入 null。
141
+ * 开启后:owner 模式下写文件前会触发 confirmationHandler 弹窗审批;
142
+ * 关闭后:owner 模式下写文件自动批准(审计仍会记录)。
143
+ * guest 模式不受影响——始终需要确认。
144
+ */
145
+ setConfirmWrites(value) {
146
+ this.confirmWrites = value;
147
+ }
148
+ /**
149
+ * 运行时切换脚本/代码执行确认开关(宿主设置面板热更新)
149
150
  *
150
- * @example
151
- * securityGuard.onWriteConfirmation(async (info) => {
152
- * return await showConfirmDialog(info.targetPath, info.description);
153
- * });
151
+ * 开启后:owner 模式下 run_code/run_project_script 执行前会触发 confirmationHandler 弹窗审批;
152
+ * 关闭后:owner 模式下脚本自动批准(审计仍会记录)。
153
+ * guest 模式不受影响——脚本执行始终需要确认。
154
154
  */
155
- onWriteConfirmation(handler) {
156
- this.confirmationHandler = handler;
155
+ setConfirmScripts(value) {
156
+ this.confirmScripts = value;
157
157
  }
158
158
  /**
159
- * 订阅审计事件
160
- * @returns 取消订阅函数
159
+ * 运行时设置「用户额外白名单」(宿主设置面板热更新)
160
+ *
161
+ * 仅操作额外项(extraRoots),基准信任根(baseRoots)永不被触碰——守住安全显式性:
162
+ * 项目目录、memora 数据目录、配置/数据目录始终允许访问,用户无法误删。
163
+ * 传空数组 = 清空额外项(仅留基准根,等价「重置」)。
164
+ * 黑名单(BLOCKED_PATTERNS)对新增路径仍强制生效——白名单是允许列表,非绕过黑名单的通行证。
161
165
  */
166
+ setAllowedPaths(extraPaths) {
167
+ if (!Array.isArray(extraPaths)) {
168
+ throw securityError('allowedPaths 必须为数组', 'setAllowedPaths 入参不是数组', [
169
+ '请传入字符串数组',
170
+ ]);
171
+ }
172
+ const normalized = [];
173
+ for (let i = 0; i < extraPaths.length && normalized.length < MAX_EXTRA_ALLOWED_PATHS; i++) {
174
+ const p = extraPaths[i];
175
+ if (typeof p !== 'string') {
176
+ throw securityError('allowedPaths 每项必须为字符串', `allowedPaths[${i}] 不是字符串`, [
177
+ 'allowedPaths 每项必须为字符串路径',
178
+ ]);
179
+ }
180
+ normalized.push(resolveRealpath(expandHome(p)));
181
+ }
182
+ this.extraRoots = normalized;
183
+ this.allowedRoots = [...this.baseRoots, ...this.extraRoots];
184
+ }
185
+ /** 订阅审计事件;@returns 取消订阅函数 */
162
186
  onAudit(listener) {
163
187
  this.listeners.push(listener);
164
188
  return () => {
@@ -168,20 +192,13 @@ export class SecurityGuard {
168
192
  };
169
193
  }
170
194
  /**
171
- * 获取最近的审计事件(深拷贝,外部不可修改内部缓冲)
172
- */
173
- getRecentAudits(limit = 10) {
174
- return this.auditBuffer.slice(-limit).map((e) => ({ ...e }));
175
- }
176
- /**
177
- * 断言路径允许访问
178
- * @throws Error 不在白名单时
179
- * @param source 调用链来源标记
195
+ * 断言路径允许访问(命中即拒绝);黑名单优先,其次白名单前缀匹配(追加 sep 防兄弟目录绕过)。
196
+ * @throws 不在白名单时
180
197
  */
181
198
  assertPathAllowed(absolutePath, tool, source) {
182
- // NFKC 规范化,防止全角字符(如 ../)绕过黑名单正则
199
+ // NFKC 规范化,防全角字符(如 ../)绕过黑名单正则
183
200
  const normalized = absolutePath.normalize('NFKC');
184
- // resolveRealpath 解析符号链接,防止通过项目内符号链接逃逸到系统目录
201
+ // 解析符号链接,防项目内符号链接逃逸到系统目录
185
202
  const resolved = resolveRealpath(normalized);
186
203
  // 1. 黑名单优先
187
204
  for (const pattern of BLOCKED_PATTERNS) {
@@ -197,7 +214,7 @@ export class SecurityGuard {
197
214
  throw securityError('禁止访问:路径命中黑名单', `路径 ${resolved} 命中黑名单规则 (${pattern})`, ['检查路径是否正确', '如需访问该路径,请联系管理员添加白名单']);
198
215
  }
199
216
  }
200
- // 2. 白名单:遍历所有允许的根目录(严格前缀匹配,追加 sep 防止兄弟目录绕过)
217
+ // 2. 白名单:严格前缀匹配(追加 sep 防兄弟目录绕过)
201
218
  for (const allowedRoot of this.allowedRoots) {
202
219
  if (resolved === allowedRoot || resolved.startsWith(allowedRoot + sep)) {
203
220
  this.emitAudit({
@@ -224,25 +241,41 @@ export class SecurityGuard {
224
241
  ]);
225
242
  }
226
243
  /**
227
- * 写入操作前请求用户确认
228
- *
229
- * 规则:
230
- * - guest 模式:始终要求确认
231
- * - owner + confirmWrites=true:要求确认
232
- * - owner + confirmWrites=false:自动批准
233
- *
234
- * 决策(fail-closed):
235
- * - 需要确认时,必须通过 onWriteConfirmation() 注入 confirmationHandler
236
- * - 未注入 handler 时,**直接拒绝写入**(返回 false)
237
- * - 理由:内核纯逻辑库不应依赖交互式终端 I/O;宿主程序负责提供确认 UI
238
- * - 安全优先:未配置 = 拒绝,避免无意识放行
239
- *
240
- * @returns true 确认通过;false 用户拒绝或未注入 handler(fail-closed)
244
+ * 写入前请求用户确认。guest 或 confirmWrites 需确认;未注入 confirmationHandler 时 fail-closed 拒绝(返回 false),
245
+ * 理由:内核纯逻辑库不依赖交互式终端 I/O,宿主负责确认 UI;安全优先:未配置 = 拒绝。
241
246
  */
242
247
  async requestWriteConfirmation(targetPath, tool, description,
243
- /** diff 内容选项(供宿主 UI 展示变更预览,自动截断到 10KB) */
248
+ /** diff 内容选项(宿主 UI 变更预览用,自动截断到 10KB) */
244
249
  options) {
245
- const needConfirm = this.permission === 'guest' || this.confirmWrites;
250
+ return this.confirmGate(targetPath, tool, description,
251
+ // 写入确认判据:guest 或 confirmWrites
252
+ this.permission === 'guest' || this.confirmWrites,
253
+ // diff 预览(仅写入场景有;脚本执行无内容预览)
254
+ {
255
+ beforeContent: truncateForDiff(options?.beforeContent),
256
+ afterContent: truncateForDiff(options?.afterContent),
257
+ });
258
+ }
259
+ /**
260
+ * 脚本/代码执行前确认(run_code / run_project_script 的执行闸)
261
+ *
262
+ * 判据与写入确认同构:guest 模式或 confirmScripts 需确认;未注入 confirmationHandler 时
263
+ * fail-closed 拒绝。owner + confirmScripts=false 自动批准(默认),审计仍记录。
264
+ * target 为脚本绝对路径(run_project_script)或描述型标识(run_code 内联代码无落盘路径)。
265
+ */
266
+ async confirmScriptRun(targetPath, tool, description) {
267
+ return this.confirmGate(targetPath, tool, description,
268
+ // 脚本执行确认判据:guest 或 confirmScripts(独立于写入确认)
269
+ this.permission === 'guest' || this.confirmScripts);
270
+ }
271
+ /**
272
+ * 确认闸公共核心(SSOT:写入确认与脚本执行确认的唯一执行路径)
273
+ *
274
+ * needConfirm=false → 自动批准(审计 write-auto);为 true 且未注入 confirmationHandler
275
+ * → fail-closed 拒绝(审计 write-decline);否则经 confirmViaHandler 走宿主确认 UI。
276
+ * diff 仅写入场景有,脚本执行不传(域留空)。
277
+ */
278
+ async confirmGate(targetPath, tool, description, needConfirm, diff) {
246
279
  // 无需确认:直接放行并记录审计
247
280
  if (!needConfirm) {
248
281
  this.emitAudit({
@@ -254,19 +287,19 @@ export class SecurityGuard {
254
287
  });
255
288
  return true;
256
289
  }
257
- // 构建确认信息(透传 diff 内容,供宿主 UI 展示变更预览)
290
+ // 构建确认信息(写入场景透传 diff 内容,供宿主 UI 展示变更预览)
258
291
  const info = {
259
292
  targetPath,
260
293
  tool,
261
294
  description,
262
295
  permission: this.permission,
263
296
  needsConfirm: needConfirm,
264
- beforeContent: truncateForDiff(options?.beforeContent),
265
- afterContent: truncateForDiff(options?.afterContent),
297
+ beforeContent: diff?.beforeContent,
298
+ afterContent: diff?.afterContent,
266
299
  };
267
300
  // 未注入 confirmationHandler 时 fail-closed 拒绝
268
301
  if (!this.confirmationHandler) {
269
- logger.warn({ targetPath, tool, permission: this.permission }, '写入确认失败:未注入 confirmationHandler,fail-closed 拒绝写入');
302
+ logger.warn({ targetPath, tool, permission: this.permission }, '执行确认失败:未注入 confirmationHandler,fail-closed 拒绝');
270
303
  this.emitAudit({
271
304
  type: 'write-decline',
272
305
  path: targetPath,
@@ -281,13 +314,8 @@ export class SecurityGuard {
281
314
  return this.confirmViaHandler(info, targetPath, tool);
282
315
  }
283
316
  /**
284
- * 通过宿主注入的 confirmationHandler 进行写入确认
285
- *
286
- * 从 requestWriteConfirmation 拆分。抛错视为拒绝(fail-closed 安全优先)。
287
- * 此方法是唯一的确认执行路径。
288
- *
289
- * @param info 确认信息(含 diff 内容)
290
- * @returns true 确认通过;false 用户拒绝或回调异常
317
+ * 通过宿主注入的 confirmationHandler 执行写入确认(唯一确认执行路径)。
318
+ * 抛错视为拒绝(fail-closed 安全优先)。
291
319
  */
292
320
  async confirmViaHandler(info, targetPath, tool) {
293
321
  try {
@@ -315,16 +343,8 @@ export class SecurityGuard {
315
343
  return false;
316
344
  }
317
345
  }
318
- /**
319
- * 触发审计事件 + 写入日志 + 通知订阅者
320
- */
346
+ /** 触发审计事件:写日志 + 通知订阅者 */
321
347
  emitAudit(event) {
322
- // 缓冲
323
- this.auditBuffer.push(event);
324
- if (this.auditBuffer.length > this.bufferLimit) {
325
- this.auditBuffer.shift();
326
- }
327
- // 写到 pino(结构化日志,方便后续检索)
328
348
  if (event.type === 'path-deny' || event.type === 'write-decline') {
329
349
  logger.warn({ audit: event }, '安全审计:拒绝');
330
350
  }