onbuzz 4.9.13 → 4.10.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 (451) hide show
  1. package/node_modules/glob/README.md +31 -5
  2. package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
  3. package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
  4. package/node_modules/glob/dist/commonjs/glob.js +2 -1
  5. package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
  6. package/node_modules/glob/dist/commonjs/index.min.js +3 -3
  7. package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
  8. package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
  9. package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
  10. package/node_modules/glob/dist/commonjs/pattern.js +4 -0
  11. package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
  12. package/node_modules/glob/dist/esm/glob.d.ts +8 -0
  13. package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
  14. package/node_modules/glob/dist/esm/glob.js +2 -1
  15. package/node_modules/glob/dist/esm/glob.js.map +1 -1
  16. package/node_modules/glob/dist/esm/index.min.js +3 -3
  17. package/node_modules/glob/dist/esm/index.min.js.map +4 -4
  18. package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
  19. package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
  20. package/node_modules/glob/dist/esm/pattern.js +4 -0
  21. package/node_modules/glob/dist/esm/pattern.js.map +1 -1
  22. package/node_modules/{@isaacs → glob/node_modules}/balanced-match/README.md +7 -10
  23. package/node_modules/{@isaacs → glob/node_modules}/balanced-match/package.json +7 -18
  24. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/README.md +3 -6
  25. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.js +6 -4
  26. package/node_modules/glob/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
  27. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.js +6 -4
  28. package/node_modules/glob/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
  29. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/package.json +11 -7
  30. package/node_modules/glob/node_modules/minimatch/README.md +76 -1
  31. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +1 -1
  32. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
  33. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -1
  34. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +4 -2
  35. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -1
  36. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +309 -55
  37. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -1
  38. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -1
  39. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +2 -4
  40. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -1
  41. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +1 -1
  42. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -1
  43. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +4 -4
  44. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -1
  45. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +81 -1
  46. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
  47. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +232 -134
  48. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
  49. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +1 -1
  50. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -1
  51. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +8 -8
  52. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -1
  53. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +1 -1
  54. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -1
  55. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
  56. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +4 -2
  57. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -1
  58. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +309 -55
  59. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -1
  60. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -1
  61. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +2 -4
  62. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
  63. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +1 -1
  64. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -1
  65. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +4 -4
  66. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -1
  67. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +81 -1
  68. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
  69. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +232 -134
  70. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -1
  71. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +1 -1
  72. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -1
  73. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +8 -8
  74. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
  75. package/node_modules/glob/node_modules/minimatch/package.json +17 -11
  76. package/node_modules/glob/package.json +10 -13
  77. package/node_modules/minipass/LICENSE.md +55 -0
  78. package/node_modules/minipass/dist/commonjs/index.d.ts +12 -16
  79. package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -1
  80. package/node_modules/minipass/dist/commonjs/index.js +13 -3
  81. package/node_modules/minipass/dist/commonjs/index.js.map +1 -1
  82. package/node_modules/minipass/dist/esm/index.d.ts +12 -16
  83. package/node_modules/minipass/dist/esm/index.d.ts.map +1 -1
  84. package/node_modules/minipass/dist/esm/index.js +3 -1
  85. package/node_modules/minipass/dist/esm/index.js.map +1 -1
  86. package/node_modules/minipass/package.json +9 -14
  87. package/node_modules/path-scurry/node_modules/lru-cache/README.md +96 -10
  88. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
  89. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
  90. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
  91. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
  92. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
  93. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
  94. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
  95. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
  96. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
  97. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
  98. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
  99. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
  100. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
  101. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
  102. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
  103. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
  104. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
  105. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
  106. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +109 -32
  107. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
  108. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +334 -197
  109. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
  110. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
  111. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
  112. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
  113. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
  114. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
  115. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
  116. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
  117. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
  118. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
  119. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
  120. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
  121. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
  122. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
  123. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
  124. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
  125. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
  126. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
  127. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
  128. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
  129. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
  130. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
  131. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
  132. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
  133. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
  134. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
  135. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
  136. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
  137. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
  138. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
  139. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
  140. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
  141. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
  142. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
  143. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
  144. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
  145. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
  146. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
  147. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
  148. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +109 -32
  149. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
  150. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +333 -196
  151. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -1
  152. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +1 -1
  153. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
  154. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
  155. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
  156. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
  157. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
  158. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
  159. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
  160. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
  161. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
  162. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
  163. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
  164. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
  165. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
  166. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
  167. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
  168. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
  169. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
  170. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
  171. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
  172. package/node_modules/path-scurry/node_modules/lru-cache/package.json +71 -18
  173. package/node_modules/path-scurry/package.json +8 -24
  174. package/package.json +1 -1
  175. package/scripts/debug-balance-probe.mjs +35 -35
  176. package/scripts/push-image.sh +43 -43
  177. package/scripts/setup-acr.sh +65 -65
  178. package/scripts/verify-optional-deps.js +96 -1
  179. package/src/__tests__/composioCliFlags.test.js +239 -239
  180. package/src/analyzers/CSSAnalyzer.js +298 -297
  181. package/src/analyzers/ConfigValidator.js +691 -690
  182. package/src/analyzers/ESLintAnalyzer.js +320 -320
  183. package/src/analyzers/JavaScriptAnalyzer.js +260 -261
  184. package/src/analyzers/PrettierFormatter.js +246 -247
  185. package/src/analyzers/PythonAnalyzer.js +283 -283
  186. package/src/analyzers/SecurityAnalyzer.js +729 -729
  187. package/src/analyzers/SparrowAnalyzer.js +341 -341
  188. package/src/analyzers/TypeScriptAnalyzer.js +247 -247
  189. package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -41
  190. package/src/analyzers/__tests__/ConfigValidator.test.js +362 -362
  191. package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -40
  192. package/src/analyzers/__tests__/PythonAnalyzer.test.js +205 -208
  193. package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -303
  194. package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -187
  195. package/src/analyzers/codeCloneDetector/analyzer.js +344 -344
  196. package/src/analyzers/codeCloneDetector/detector.js +250 -250
  197. package/src/analyzers/codeCloneDetector/index.js +194 -192
  198. package/src/analyzers/codeCloneDetector/parser.js +199 -199
  199. package/src/core/__tests__/agentPool.test.js +866 -866
  200. package/src/core/__tests__/agentPoolAutoResume.test.js +209 -209
  201. package/src/core/__tests__/agentPoolWakeOnMessage.test.js +315 -315
  202. package/src/core/__tests__/agentScheduler.emptyResponseChatStall.test.js +213 -213
  203. package/src/core/__tests__/agentScheduler.errorCategorisation.test.js +246 -246
  204. package/src/core/__tests__/agentScheduler.firstChunkTimeout.test.js +138 -138
  205. package/src/core/__tests__/agentScheduler.modeTransitions.test.js +233 -233
  206. package/src/core/__tests__/agentScheduler.nativePromptPick.test.js +319 -319
  207. package/src/core/__tests__/agentScheduler.taskLifecycleInstruction.test.js +78 -78
  208. package/src/core/__tests__/agentScheduler.visualizer.test.js +258 -258
  209. package/src/core/__tests__/flowCheckpointStore.test.js +140 -140
  210. package/src/core/__tests__/flowEndToEnd.test.js +565 -565
  211. package/src/core/__tests__/flowFieldMapping.test.js +188 -189
  212. package/src/core/__tests__/flowLintClientMirror.test.js +96 -98
  213. package/src/core/__tests__/flowSavePayload.test.js +170 -169
  214. package/src/core/__tests__/flowTemplates.test.js +311 -311
  215. package/src/core/__tests__/flowVersionStore.test.js +123 -123
  216. package/src/core/__tests__/messageProcessor.test.js +669 -669
  217. package/src/core/__tests__/stateManager.test.js +0 -1
  218. package/src/core/agentPool.js +2474 -2475
  219. package/src/core/agentScheduler.js +1 -4
  220. package/src/core/contextManager.js +708 -708
  221. package/src/core/flowExecutor.js +1510 -1510
  222. package/src/core/flowFieldMapping.js +136 -138
  223. package/src/core/messageProcessor.js +953 -954
  224. package/src/core/orchestrator.js +593 -595
  225. package/src/core/stateManager.js +1765 -1752
  226. package/src/index.js +1221 -1221
  227. package/src/interfaces/__tests__/archivedAgentDelete.test.js +207 -207
  228. package/src/interfaces/__tests__/bulkAgentRoute.test.js +361 -361
  229. package/src/interfaces/__tests__/imageServing.test.js +228 -228
  230. package/src/interfaces/__tests__/remoteSessionAuth.test.js +308 -308
  231. package/src/interfaces/__tests__/videoJobsRoutes.test.js +178 -179
  232. package/src/interfaces/__tests__/webServer.marketplace.test.js +629 -629
  233. package/src/interfaces/schedulerRoutes.js +50 -50
  234. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +341 -350
  235. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -156
  236. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +325 -330
  237. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +385 -388
  238. package/src/interfaces/terminal/api/session.js +265 -266
  239. package/src/interfaces/terminal/api/websocket.js +496 -497
  240. package/src/interfaces/terminal/components/AgentCreator.js +691 -705
  241. package/src/interfaces/terminal/components/AgentEditor.js +676 -678
  242. package/src/interfaces/terminal/components/AgentSwitcher.js +331 -330
  243. package/src/interfaces/terminal/components/ErrorPanel.js +263 -264
  244. package/src/interfaces/terminal/components/Header.js +28 -28
  245. package/src/interfaces/terminal/components/Layout.js +598 -603
  246. package/src/interfaces/terminal/components/MessageList.js +280 -281
  247. package/src/interfaces/terminal/components/SettingsPanel.js +410 -415
  248. package/src/interfaces/terminal/components/StatusBar.js +2 -0
  249. package/src/interfaces/terminal/index.js +168 -168
  250. package/src/interfaces/terminal/state/useAgentControl.js +496 -496
  251. package/src/interfaces/terminal/state/useAgents.js +537 -537
  252. package/src/interfaces/terminal/state/useMessages.js +629 -630
  253. package/src/interfaces/terminal/state/useTools.js +554 -554
  254. package/src/interfaces/terminal/utils/debugLogger.js +44 -44
  255. package/src/interfaces/terminal/utils/settingsStorage.js +232 -232
  256. package/src/interfaces/webServer.js +7578 -7579
  257. package/src/interfaces/webServer.js.bak +7046 -7046
  258. package/src/modules/fileExplorer/__tests__/zipDownload.test.js +237 -237
  259. package/src/modules/fileExplorer/controller.js +470 -469
  260. package/src/modules/fileExplorer/routes.js +285 -286
  261. package/src/modules/widget/__tests__/isDisabled.test.js +41 -41
  262. package/src/modules/widget/__tests__/routes.test.js +677 -678
  263. package/src/modules/widget/__tests__/runtime.test.js +401 -401
  264. package/src/modules/widget/__tests__/versioning.test.js +309 -309
  265. package/src/modules/widget/__tests__/webComponentRuntime.test.js +565 -565
  266. package/src/modules/widget/__tests__/widgetTool.test.js +316 -316
  267. package/src/modules/widget/routes.js +435 -435
  268. package/src/modules/widget/runtime/bundle.js +640 -640
  269. package/src/modules/widget/runtime/webComponentBundle.js +470 -470
  270. package/src/modules/widget/schema.js +182 -181
  271. package/src/modules/widget/widgetTool.js +1389 -1389
  272. package/src/services/__tests__/agentActivityService.test.js +401 -402
  273. package/src/services/__tests__/benchmarkService.test.js +184 -184
  274. package/src/services/__tests__/contextInjectionService.test.js +246 -246
  275. package/src/services/__tests__/conversationQuery.test.js +721 -723
  276. package/src/services/__tests__/credentialVault.test.js +469 -469
  277. package/src/services/__tests__/discordService.integration.test.js +638 -639
  278. package/src/services/__tests__/flowContextService.test.js +590 -590
  279. package/src/services/__tests__/memoryService.test.js +1 -1
  280. package/src/services/__tests__/messageSource.test.js +380 -380
  281. package/src/services/__tests__/modelRouterNaming.test.js +111 -111
  282. package/src/services/__tests__/projectDetector.test.js +34 -34
  283. package/src/services/__tests__/promptService.test.js +242 -242
  284. package/src/services/__tests__/telegramService.test.js +941 -941
  285. package/src/services/__tests__/tokenCountingService.test.js +48 -48
  286. package/src/services/agentActivityService.js +419 -420
  287. package/src/services/aiService.js +2997 -3001
  288. package/src/services/apiKeyManager.js +359 -359
  289. package/src/services/benchmarkService.js +196 -196
  290. package/src/services/codebaseKnowledgeService.js +2 -2
  291. package/src/services/composioService.js +738 -738
  292. package/src/services/conversationCompactionService.js +1258 -1257
  293. package/src/services/credentialVault.js +685 -685
  294. package/src/services/discordService.js +792 -793
  295. package/src/services/embeddings/__tests__/azureCustomProvider.test.js +232 -232
  296. package/src/services/embeddings/__tests__/embeddingService.test.js +417 -417
  297. package/src/services/embeddings/__tests__/localProvider.test.js +263 -263
  298. package/src/services/embeddings/autoRecall.js +218 -219
  299. package/src/services/embeddings/indexers/__tests__/agentIndexer.test.js +232 -232
  300. package/src/services/embeddings/indexers/__tests__/memoryIndexer.test.js +418 -418
  301. package/src/services/embeddings/indexers/__tests__/reminisceIndexer.test.js +356 -357
  302. package/src/services/embeddings/indexers/__tests__/skillsIndexer.test.js +145 -145
  303. package/src/services/embeddings/indexers/__tests__/taskIndexer.test.js +146 -146
  304. package/src/services/embeddings/indexers/composioIndexer.js +279 -279
  305. package/src/services/embeddings/providerInterface.js +206 -206
  306. package/src/services/embeddings/providers/localProvider.js +11 -7
  307. package/src/services/embeddings/providers/openaiProvider.js +101 -101
  308. package/src/services/embeddings/vectorStore/inMemoryJsonStore.js +356 -356
  309. package/src/services/errorHandler.js +809 -809
  310. package/src/services/flowContextService.js +586 -586
  311. package/src/services/grounding/MockAdapter.js +125 -125
  312. package/src/services/modelRouterService.js +26 -31
  313. package/src/services/modelsService.js +322 -322
  314. package/src/services/ollamaService.js +452 -452
  315. package/src/services/projectDetector.js +403 -404
  316. package/src/services/promptService.js +418 -418
  317. package/src/services/qualityInspector.js +795 -795
  318. package/src/services/scheduleService.js +726 -726
  319. package/src/services/serviceRegistry.js +386 -386
  320. package/src/services/telegrafBot.js +174 -174
  321. package/src/services/telegramService.js +1972 -1972
  322. package/src/services/visualEditorBridge.js +1033 -1033
  323. package/src/services/visualEditorServer.js +1769 -1774
  324. package/src/services/whatsappService.js +667 -668
  325. package/src/tools/__tests__/agentCommunicationTool.findAgent.test.js +226 -226
  326. package/src/tools/__tests__/agentCommunicationTool.test.js +3 -3
  327. package/src/tools/__tests__/agentDelayTool.test.js +342 -342
  328. package/src/tools/__tests__/baseTool.test.js +3 -3
  329. package/src/tools/__tests__/codeMapTool.test.js +915 -915
  330. package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -309
  331. package/src/tools/__tests__/fileTreeTool.test.js +274 -274
  332. package/src/tools/__tests__/filesystemTool.test.js +815 -815
  333. package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -252
  334. package/src/tools/__tests__/imageTool.validator.test.js +194 -194
  335. package/src/tools/__tests__/jobDoneTool.test.js +580 -581
  336. package/src/tools/__tests__/memoryTool.forgetStale.test.js +272 -272
  337. package/src/tools/__tests__/memoryTool.reminisce.test.js +2 -2
  338. package/src/tools/__tests__/memoryTool.reminisceSemanticSearch.test.js +301 -301
  339. package/src/tools/__tests__/memoryTool.semanticSearch.test.js +405 -405
  340. package/src/tools/__tests__/memoryTool.teamPool.test.js +293 -293
  341. package/src/tools/__tests__/memoryTool.test.js +1 -1
  342. package/src/tools/__tests__/seekTool.test.js +282 -282
  343. package/src/tools/__tests__/skillsTool.search.test.js +164 -164
  344. package/src/tools/__tests__/skillsTool.test.js +226 -226
  345. package/src/tools/__tests__/staticAnalysisTool.test.js +509 -509
  346. package/src/tools/__tests__/taskManagerTool.discipline.test.js +137 -137
  347. package/src/tools/__tests__/taskManagerTool.search.test.js +143 -143
  348. package/src/tools/__tests__/taskManagerTool.test.js +866 -866
  349. package/src/tools/__tests__/terminalTool.test.js +448 -448
  350. package/src/tools/__tests__/toolShapeForgiveness.test.js +259 -260
  351. package/src/tools/__tests__/userPromptTool.test.js +297 -297
  352. package/src/tools/__tests__/videoTool.jobs.test.js +147 -147
  353. package/src/tools/__tests__/webTool.e2e.test.js +609 -603
  354. package/src/tools/__tests__/webTool.unit.test.js +195 -195
  355. package/src/tools/__tests__/webTool.visionModel.test.js +75 -75
  356. package/src/tools/agentCommunicationTool.js +8 -10
  357. package/src/tools/agentDelayTool.js +496 -497
  358. package/src/tools/asyncToolManager.js +602 -603
  359. package/src/tools/baseTool.js +12 -11
  360. package/src/tools/cloneDetectionTool.js +576 -581
  361. package/src/tools/codeMapTool.js +0 -6
  362. package/src/tools/composioTool.js +617 -617
  363. package/src/tools/dependencyResolverTool.js +1211 -1212
  364. package/src/tools/desktop/DesktopTool.js +629 -638
  365. package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -306
  366. package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -507
  367. package/src/tools/desktop/__tests__/osController.test.js +364 -364
  368. package/src/tools/desktop/osController.js +491 -491
  369. package/src/tools/docxTool.js +623 -623
  370. package/src/tools/excelTool.js +636 -636
  371. package/src/tools/fileContentReplaceTool.js +5 -7
  372. package/src/tools/fileSystemTool.js +12 -19
  373. package/src/tools/fileTreeTool.js +840 -840
  374. package/src/tools/foundryWebSearchTool.js +273 -273
  375. package/src/tools/helpTool.js +198 -198
  376. package/src/tools/imageTool.js +1397 -1397
  377. package/src/tools/importAnalyzerTool.js +1056 -1056
  378. package/src/tools/jobDoneTool.js +495 -495
  379. package/src/tools/memoryTool.js +1 -1
  380. package/src/tools/office/pres/__tests__/presSystem.test.js +365 -365
  381. package/src/tools/office/pres/archetypes/agenda.js +61 -61
  382. package/src/tools/office/pres/archetypes/bentoGrid.js +218 -219
  383. package/src/tools/office/pres/archetypes/bigStat.js +140 -142
  384. package/src/tools/office/pres/archetypes/closing.js +70 -70
  385. package/src/tools/office/pres/archetypes/hero.js +70 -70
  386. package/src/tools/office/pres/archetypes/productHero.js +93 -94
  387. package/src/tools/office/pres/archetypes/table.js +73 -74
  388. package/src/tools/office/pres/backgrounds/orb.js +66 -66
  389. package/src/tools/office/pres/components.js +422 -423
  390. package/src/tools/officeTool.js +441 -441
  391. package/src/tools/pdfTool.js +625 -627
  392. package/src/tools/platformControlTool.js +1081 -1081
  393. package/src/tools/seekTool.js +917 -918
  394. package/src/tools/skillsTool.js +1 -1
  395. package/src/tools/staticAnalysisTool.js +2143 -2146
  396. package/src/tools/taskManagerTool.js +3324 -3324
  397. package/src/tools/terminalTool.js +2615 -2618
  398. package/src/tools/videoTool.js +1303 -1303
  399. package/src/tools/visionTool.js +508 -508
  400. package/src/tools/visualEditorTool.js +1289 -1290
  401. package/src/tools/webTool.js +3368 -3368
  402. package/src/tools/whatsappTool.js +464 -464
  403. package/src/types/__tests__/agent.test.js +499 -499
  404. package/src/types/__tests__/contextReference.test.js +606 -606
  405. package/src/types/__tests__/conversation.test.js +555 -555
  406. package/src/types/__tests__/toolCommand.test.js +584 -584
  407. package/src/types/contextReference.js +974 -971
  408. package/src/types/conversation.js +729 -729
  409. package/src/types/toolCommand.js +746 -746
  410. package/src/utilities/__tests__/attachmentValidator.test.js +80 -80
  411. package/src/utilities/__tests__/auditReport.test.js +328 -328
  412. package/src/utilities/__tests__/directoryAccessManager.test.js +388 -388
  413. package/src/utilities/__tests__/jsonRepair.test.js +103 -104
  414. package/src/utilities/__tests__/modeTransitionReasons.test.js +105 -105
  415. package/src/utilities/__tests__/platformUtils.test.js +80 -87
  416. package/src/utilities/__tests__/structuredFileValidator.test.js +261 -263
  417. package/src/utilities/__tests__/toolConstants.test.js +92 -94
  418. package/src/utilities/__tests__/useIsTouchDevice.detect.test.js +114 -114
  419. package/src/utilities/__tests__/webUiUtilSync.test.js +117 -117
  420. package/src/utilities/attachmentValidator.js +284 -288
  421. package/src/utilities/authCache.js.backup-1779570472481 +121 -121
  422. package/src/utilities/browserStealth.js +631 -630
  423. package/src/utilities/configManager.js +616 -617
  424. package/src/utilities/directoryAccessManager.js +564 -565
  425. package/src/utilities/fileProcessor.js +308 -307
  426. package/src/utilities/humanBehavior.js +454 -453
  427. package/src/utilities/logger.js +479 -479
  428. package/src/utilities/structuredFileValidator.js +696 -699
  429. package/src/utilities/tagParser.js +5 -10
  430. package/src/utilities/userDataDir.js +308 -308
  431. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +0 -1
  432. package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +0 -1
  433. package/node_modules/minipass/LICENSE +0 -15
  434. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/LICENSE.md +0 -0
  435. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts +0 -0
  436. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts.map +0 -0
  437. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js +0 -0
  438. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js.map +0 -0
  439. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/package.json +0 -0
  440. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts +0 -0
  441. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts.map +0 -0
  442. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js +0 -0
  443. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js.map +0 -0
  444. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/package.json +0 -0
  445. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/LICENSE +0 -0
  446. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts +0 -0
  447. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts.map +0 -0
  448. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/package.json +0 -0
  449. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts +0 -0
  450. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts.map +0 -0
  451. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/package.json +0 -0
@@ -1,566 +1,565 @@
1
- /**
2
- * DirectoryAccessManager - Manage directory access permissions for agents
3
- *
4
- * Purpose:
5
- * - Control agent access to directories and files
6
- * - Distinguish between read-only and write-enabled directories
7
- * - Validate paths against access permissions
8
- * - Provide working directory management
9
- * - Support both absolute and relative path resolution
10
- */
11
-
12
- import path from 'path';
13
- import fs from 'fs/promises';
14
- import os from 'os';
15
- import { getSystemRestrictedPaths } from './platformUtils.js';
16
-
17
- class DirectoryAccessManager {
18
- constructor(config = {}, logger = null) {
19
- this.logger = logger;
20
- this.config = config;
21
-
22
- // Default system restrictions (platform-aware from platformUtils)
23
- this.systemRestrictedPaths = [
24
- ...getSystemRestrictedPaths(),
25
- // User sensitive directories (cross-platform)
26
- path.join(os.homedir(), '.ssh'),
27
- path.join(os.homedir(), '.aws'),
28
- path.join(os.homedir(), '.config'),
29
- path.join(os.homedir(), '.gnupg'),
30
- // Common package managers and git internals
31
- 'node_modules/.bin',
32
- '.git/objects',
33
- '.git/hooks'
34
- ];
35
- }
36
-
37
- /**
38
- * Create directory access configuration for an agent
39
- * @param {Object} options - Access configuration options
40
- * @returns {Object} Directory access configuration
41
- */
42
- createDirectoryAccess(options = {}) {
43
- const {
44
- workingDirectory = process.cwd(),
45
- readOnlyDirectories = [],
46
- writeEnabledDirectories = [],
47
- restrictToProject = true,
48
- allowSystemAccess = false,
49
- customRestrictions = []
50
- } = options;
51
-
52
- // Normalize all paths to absolute
53
- const workingDir = path.resolve(workingDirectory);
54
- const readOnlyDirs = readOnlyDirectories.map(dir => this.normalizePath(dir, workingDir));
55
- const writeEnabledDirs = writeEnabledDirectories.map(dir => this.normalizePath(dir, workingDir));
56
-
57
- // If restrict to project, ensure working directory is included
58
- const finalReadOnlyDirs = restrictToProject
59
- ? [...new Set([...readOnlyDirs, workingDir])]
60
- : readOnlyDirs;
61
-
62
- const finalWriteEnabledDirs = restrictToProject
63
- ? writeEnabledDirs.filter(dir => this.isPathWithinDirectory(dir, workingDir))
64
- : writeEnabledDirs;
65
-
66
- return {
67
- workingDirectory: workingDir,
68
- readOnlyDirectories: finalReadOnlyDirs,
69
- writeEnabledDirectories: finalWriteEnabledDirs,
70
- restrictToProject,
71
- allowSystemAccess,
72
- customRestrictions: customRestrictions.map(restriction => path.resolve(restriction)),
73
- createdAt: new Date().toISOString(),
74
- version: '1.0'
75
- };
76
- }
77
-
78
- /**
79
- * Validate if a path can be accessed for reading
80
- * @param {string} targetPath - Path to validate
81
- * @param {Object} accessConfig - Directory access configuration
82
- * @returns {Object} Validation result
83
- */
84
- validateReadAccess(targetPath, accessConfig) {
85
- try {
86
- const resolvedPath = this.resolvePath(targetPath, accessConfig.workingDirectory);
87
-
88
- // Check system restrictions first
89
- if (!accessConfig.allowSystemAccess && this.isSystemRestrictedPath(resolvedPath)) {
90
- return {
91
- allowed: false,
92
- reason: 'System path access denied',
93
- path: resolvedPath,
94
- category: 'system_restricted'
95
- };
96
- }
97
-
98
- // Check custom restrictions
99
- if (this.isCustomRestricted(resolvedPath, accessConfig.customRestrictions)) {
100
- return {
101
- allowed: false,
102
- reason: 'Custom restriction applied',
103
- path: resolvedPath,
104
- category: 'custom_restricted'
105
- };
106
- }
107
-
108
- // If restricting to project, ensure path is within allowed boundaries
109
- if (accessConfig.restrictToProject) {
110
- // Build list of allowed directories, using workingDirectory as fallback if lists are empty
111
- const allowedDirs = [
112
- ...(accessConfig.readOnlyDirectories || []),
113
- ...(accessConfig.writeEnabledDirectories || [])
114
- ];
115
-
116
- // If no explicit directories configured, use workingDirectory as the project scope
117
- if (allowedDirs.length === 0 && accessConfig.workingDirectory) {
118
- allowedDirs.push(accessConfig.workingDirectory);
119
- }
120
-
121
- const isWithinProject = this.isPathWithinAnyDirectory(resolvedPath, allowedDirs);
122
-
123
- if (!isWithinProject) {
124
- return {
125
- allowed: false,
126
- reason: 'Path outside project scope',
127
- path: resolvedPath,
128
- category: 'project_restricted'
129
- };
130
- }
131
- }
132
-
133
- // Check if path is within any allowed directory
134
- const isWithinAllowed = this.isPathWithinAnyDirectory(resolvedPath, [
135
- ...accessConfig.readOnlyDirectories,
136
- ...accessConfig.writeEnabledDirectories
137
- ]);
138
-
139
- if (!isWithinAllowed && accessConfig.readOnlyDirectories.length > 0) {
140
- return {
141
- allowed: false,
142
- reason: 'Path not in allowed directories',
143
- path: resolvedPath,
144
- category: 'directory_restricted'
145
- };
146
- }
147
-
148
- return {
149
- allowed: true,
150
- path: resolvedPath,
151
- category: 'allowed'
152
- };
153
-
154
- } catch (error) {
155
- return {
156
- allowed: false,
157
- reason: `Path validation error: ${error.message}`,
158
- path: targetPath,
159
- category: 'validation_error'
160
- };
161
- }
162
- }
163
-
164
- /**
165
- * Validate if a path can be accessed for writing
166
- * @param {string} targetPath - Path to validate
167
- * @param {Object} accessConfig - Directory access configuration
168
- * @returns {Object} Validation result
169
- */
170
- validateWriteAccess(targetPath, accessConfig) {
171
- // First check read access
172
- const readResult = this.validateReadAccess(targetPath, accessConfig);
173
- if (!readResult.allowed) {
174
- return {
175
- ...readResult,
176
- writeAllowed: false
177
- };
178
- }
179
-
180
- const resolvedPath = readResult.path;
181
-
182
- // Build effective write-enabled directories list
183
- // If writeEnabledDirectories is empty but we have a workingDirectory,
184
- // treat the workingDirectory as implicitly write-enabled
185
- let effectiveWriteEnabled = [...(accessConfig.writeEnabledDirectories || [])];
186
-
187
- if (effectiveWriteEnabled.length === 0 && accessConfig.workingDirectory) {
188
- // Fallback: working directory is implicitly write-enabled when no explicit dirs configured
189
- effectiveWriteEnabled = [accessConfig.workingDirectory];
190
- this.logger?.debug('No writeEnabledDirectories configured, using workingDirectory as fallback', {
191
- workingDirectory: accessConfig.workingDirectory
192
- });
193
- }
194
-
195
- // Check if path is within write-enabled directories
196
- const isWithinWriteEnabled = this.isPathWithinAnyDirectory(
197
- resolvedPath,
198
- effectiveWriteEnabled
199
- );
200
-
201
- if (!isWithinWriteEnabled) {
202
- // Check if it's in read-only directories
203
- const isWithinReadOnly = this.isPathWithinAnyDirectory(
204
- resolvedPath,
205
- accessConfig.readOnlyDirectories || []
206
- );
207
-
208
- if (isWithinReadOnly) {
209
- return {
210
- allowed: false,
211
- writeAllowed: false,
212
- reason: 'Path is in read-only directory',
213
- path: resolvedPath,
214
- category: 'read_only_restricted'
215
- };
216
- }
217
-
218
- return {
219
- allowed: false,
220
- writeAllowed: false,
221
- reason: 'Path not in write-enabled directories',
222
- path: resolvedPath,
223
- category: 'write_restricted'
224
- };
225
- }
226
-
227
- return {
228
- allowed: true,
229
- writeAllowed: true,
230
- path: resolvedPath,
231
- category: 'write_allowed'
232
- };
233
- }
234
-
235
- /**
236
- * Get the effective working directory for an agent
237
- * @param {Object} accessConfig - Directory access configuration
238
- * @returns {string} Working directory path
239
- */
240
- getWorkingDirectory(accessConfig) {
241
- return accessConfig.workingDirectory || process.cwd();
242
- }
243
-
244
- /**
245
- * List accessible directories for an agent
246
- * @param {Object} accessConfig - Directory access configuration
247
- * @returns {Object} Directory listing with permissions
248
- */
249
- getAccessibleDirectories(accessConfig) {
250
- return {
251
- workingDirectory: accessConfig.workingDirectory,
252
- readOnly: [...accessConfig.readOnlyDirectories],
253
- writeEnabled: [...accessConfig.writeEnabledDirectories],
254
- projectRestricted: accessConfig.restrictToProject,
255
- systemAccessAllowed: accessConfig.allowSystemAccess,
256
- totalDirectories: accessConfig.readOnlyDirectories.length + accessConfig.writeEnabledDirectories.length
257
- };
258
- }
259
-
260
- /**
261
- * Update directory access configuration
262
- * @param {Object} currentConfig - Current access configuration
263
- * @param {Object} updates - Updates to apply
264
- * @returns {Object} Updated configuration
265
- */
266
- updateDirectoryAccess(currentConfig, updates) {
267
- const updatedConfig = { ...currentConfig };
268
-
269
- if (updates.workingDirectory) {
270
- updatedConfig.workingDirectory = path.resolve(updates.workingDirectory);
271
- }
272
-
273
- if (updates.readOnlyDirectories !== undefined) {
274
- updatedConfig.readOnlyDirectories = updates.readOnlyDirectories.map(dir =>
275
- this.normalizePath(dir, updatedConfig.workingDirectory)
276
- );
277
- }
278
-
279
- if (updates.writeEnabledDirectories !== undefined) {
280
- updatedConfig.writeEnabledDirectories = updates.writeEnabledDirectories.map(dir =>
281
- this.normalizePath(dir, updatedConfig.workingDirectory)
282
- );
283
- }
284
-
285
- if (updates.restrictToProject !== undefined) {
286
- updatedConfig.restrictToProject = updates.restrictToProject;
287
- }
288
-
289
- if (updates.allowSystemAccess !== undefined) {
290
- updatedConfig.allowSystemAccess = updates.allowSystemAccess;
291
- }
292
-
293
- if (updates.customRestrictions !== undefined) {
294
- updatedConfig.customRestrictions = updates.customRestrictions.map(restriction =>
295
- path.resolve(restriction)
296
- );
297
- }
298
-
299
- updatedConfig.version = currentConfig.version || '1.0';
300
- updatedConfig.updatedAt = new Date().toISOString();
301
-
302
- return updatedConfig;
303
- }
304
-
305
- /**
306
- * Validate directory access configuration
307
- * @param {Object} accessConfig - Configuration to validate
308
- * @returns {Object} Validation result
309
- */
310
- validateAccessConfiguration(accessConfig) {
311
- const errors = [];
312
- const warnings = [];
313
-
314
- // Validate working directory exists
315
- if (!accessConfig.workingDirectory) {
316
- errors.push('Working directory is required');
317
- } else {
318
- // Convert relative paths to absolute paths relative to process.cwd()
319
- if (!path.isAbsolute(accessConfig.workingDirectory)) {
320
- accessConfig.workingDirectory = path.resolve(process.cwd(), accessConfig.workingDirectory);
321
- }
322
- }
323
-
324
- // Validate directory arrays
325
- if (!Array.isArray(accessConfig.readOnlyDirectories)) {
326
- errors.push('readOnlyDirectories must be an array');
327
- } else {
328
- // Convert relative paths to absolute paths
329
- accessConfig.readOnlyDirectories = accessConfig.readOnlyDirectories.map(dir =>
330
- path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir)
331
- );
332
- }
333
-
334
- if (!Array.isArray(accessConfig.writeEnabledDirectories)) {
335
- errors.push('writeEnabledDirectories must be an array');
336
- } else {
337
- // Convert relative paths to absolute paths
338
- accessConfig.writeEnabledDirectories = accessConfig.writeEnabledDirectories.map(dir =>
339
- path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir)
340
- );
341
- }
342
-
343
- // Check for overlapping directories
344
- if (accessConfig.readOnlyDirectories && accessConfig.writeEnabledDirectories) {
345
- const overlapping = this.findOverlappingPaths(
346
- accessConfig.readOnlyDirectories,
347
- accessConfig.writeEnabledDirectories
348
- );
349
-
350
- if (overlapping.length > 0) {
351
- warnings.push(`Overlapping directories found: ${overlapping.join(', ')}`);
352
- }
353
- }
354
-
355
- // Check for system path access
356
- if (accessConfig.allowSystemAccess) {
357
- warnings.push('System path access is enabled - use with caution');
358
- }
359
-
360
- // Validate paths exist (async check would be needed in real implementation)
361
- const allPaths = [
362
- ...accessConfig.readOnlyDirectories,
363
- ...accessConfig.writeEnabledDirectories
364
- ];
365
-
366
- for (const dirPath of allPaths) {
367
- if (!path.isAbsolute(dirPath)) {
368
- errors.push(`Directory path must be absolute: ${dirPath}`);
369
- }
370
- }
371
-
372
- return {
373
- valid: errors.length === 0,
374
- errors,
375
- warnings,
376
- summary: {
377
- readOnlyCount: accessConfig.readOnlyDirectories?.length || 0,
378
- writeEnabledCount: accessConfig.writeEnabledDirectories?.length || 0,
379
- restrictToProject: accessConfig.restrictToProject,
380
- allowSystemAccess: accessConfig.allowSystemAccess
381
- }
382
- };
383
- }
384
-
385
- /**
386
- * Create relative path from absolute path within accessible directories
387
- * @param {string} absolutePath - Absolute path to convert
388
- * @param {Object} accessConfig - Directory access configuration
389
- * @returns {string} Relative path or original if not within accessible directories
390
- */
391
- createRelativePath(absolutePath, accessConfig) {
392
- const allDirectories = [
393
- ...accessConfig.readOnlyDirectories,
394
- ...accessConfig.writeEnabledDirectories,
395
- accessConfig.workingDirectory
396
- ];
397
-
398
- for (const dir of allDirectories) {
399
- if (this.isPathWithinDirectory(absolutePath, dir)) {
400
- return path.relative(dir, absolutePath);
401
- }
402
- }
403
-
404
- return absolutePath;
405
- }
406
-
407
- /**
408
- * Resolve path relative to working directory or as absolute
409
- * @private
410
- */
411
- resolvePath(targetPath, workingDirectory) {
412
- if (path.isAbsolute(targetPath)) {
413
- return path.normalize(targetPath);
414
- }
415
- return path.resolve(workingDirectory, targetPath);
416
- }
417
-
418
- /**
419
- * Normalize path to absolute, resolving relative to working directory
420
- * @private
421
- */
422
- normalizePath(targetPath, workingDirectory) {
423
- if (path.isAbsolute(targetPath)) {
424
- return path.normalize(targetPath);
425
- }
426
- return path.resolve(workingDirectory, targetPath);
427
- }
428
-
429
- /**
430
- * Check if path is within a directory
431
- * Uses case-insensitive comparison on macOS and Windows
432
- * @private
433
- */
434
- isPathWithinDirectory(targetPath, parentDirectory) {
435
- // macOS (APFS/HFS+) and Windows (NTFS) are case-insensitive
436
- const caseInsensitive = process.platform === 'darwin' || process.platform === 'win32';
437
-
438
- // Normalize paths for comparison
439
- let normalizedTarget = path.normalize(targetPath);
440
- let normalizedParent = path.normalize(parentDirectory);
441
-
442
- // Apply case-insensitive comparison if needed
443
- if (caseInsensitive) {
444
- normalizedTarget = normalizedTarget.toLowerCase();
445
- normalizedParent = normalizedParent.toLowerCase();
446
- }
447
-
448
- const relative = path.relative(normalizedParent, normalizedTarget);
449
- return !relative.startsWith('..') && !path.isAbsolute(relative);
450
- }
451
-
452
- /**
453
- * Check if path is within any of the provided directories
454
- * @private
455
- */
456
- isPathWithinAnyDirectory(targetPath, directories) {
457
- return directories.some(dir => this.isPathWithinDirectory(targetPath, dir));
458
- }
459
-
460
- /**
461
- * Check if path is system restricted
462
- * Uses case-insensitive comparison on macOS and Windows
463
- * @private
464
- */
465
- isSystemRestrictedPath(targetPath) {
466
- // macOS (APFS/HFS+) and Windows (NTFS) are case-insensitive
467
- const caseInsensitive = process.platform === 'darwin' || process.platform === 'win32';
468
-
469
- const normalizedTarget = caseInsensitive ? targetPath.toLowerCase() : targetPath;
470
-
471
- return this.systemRestrictedPaths.some(restrictedPath => {
472
- const normalizedRestricted = caseInsensitive ? restrictedPath.toLowerCase() : restrictedPath;
473
- return normalizedTarget.startsWith(normalizedRestricted) || normalizedTarget === normalizedRestricted;
474
- });
475
- }
476
-
477
- /**
478
- * Check if path is custom restricted
479
- * @private
480
- */
481
- isCustomRestricted(targetPath, customRestrictions) {
482
- if (!customRestrictions || customRestrictions.length === 0) {
483
- return false;
484
- }
485
-
486
- return customRestrictions.some(restriction => {
487
- return targetPath.startsWith(restriction) || targetPath === restriction;
488
- });
489
- }
490
-
491
- /**
492
- * Find overlapping paths between two arrays
493
- * @private
494
- */
495
- findOverlappingPaths(paths1, paths2) {
496
- const overlapping = [];
497
-
498
- for (const path1 of paths1) {
499
- for (const path2 of paths2) {
500
- if (this.isPathWithinDirectory(path1, path2) || this.isPathWithinDirectory(path2, path1)) {
501
- overlapping.push(`${path1} <-> ${path2}`);
502
- }
503
- }
504
- }
505
-
506
- return overlapping;
507
- }
508
-
509
- /**
510
- * Get directory access summary for logging/debugging
511
- * @param {Object} accessConfig - Directory access configuration
512
- * @returns {Object} Summary object
513
- */
514
- getAccessSummary(accessConfig) {
515
- return {
516
- workingDirectory: accessConfig.workingDirectory,
517
- readOnlyCount: accessConfig.readOnlyDirectories.length,
518
- writeEnabledCount: accessConfig.writeEnabledDirectories.length,
519
- projectRestricted: accessConfig.restrictToProject,
520
- systemAccessAllowed: accessConfig.allowSystemAccess,
521
- customRestrictionsCount: accessConfig.customRestrictions?.length || 0,
522
- configVersion: accessConfig.version || 'unknown',
523
- lastUpdated: accessConfig.updatedAt || accessConfig.createdAt
524
- };
525
- }
526
-
527
- /**
528
- * Create default directory access for project-based agents
529
- * @param {string} projectDir - Project directory path
530
- * @returns {Object} Default directory access configuration
531
- */
532
- static createProjectDefaults(projectDir) {
533
- const resolvedProject = path.resolve(projectDir);
534
-
535
- return {
536
- workingDirectory: resolvedProject,
537
- readOnlyDirectories: [resolvedProject],
538
- writeEnabledDirectories: [resolvedProject],
539
- restrictToProject: true,
540
- allowSystemAccess: false,
541
- customRestrictions: [],
542
- createdAt: new Date().toISOString(),
543
- version: '1.0'
544
- };
545
- }
546
-
547
- /**
548
- * Create permissive directory access (use with caution)
549
- * @param {string} workingDir - Working directory
550
- * @returns {Object} Permissive directory access configuration
551
- */
552
- static createPermissiveDefaults(workingDir = process.cwd()) {
553
- return {
554
- workingDirectory: path.resolve(workingDir),
555
- readOnlyDirectories: [os.homedir()],
556
- writeEnabledDirectories: [path.resolve(workingDir)],
557
- restrictToProject: false,
558
- allowSystemAccess: false,
559
- customRestrictions: [],
560
- createdAt: new Date().toISOString(),
561
- version: '1.0'
562
- };
563
- }
564
- }
565
-
1
+ /**
2
+ * DirectoryAccessManager - Manage directory access permissions for agents
3
+ *
4
+ * Purpose:
5
+ * - Control agent access to directories and files
6
+ * - Distinguish between read-only and write-enabled directories
7
+ * - Validate paths against access permissions
8
+ * - Provide working directory management
9
+ * - Support both absolute and relative path resolution
10
+ */
11
+
12
+ import path from 'path';
13
+ import os from 'os';
14
+ import { getSystemRestrictedPaths } from './platformUtils.js';
15
+
16
+ class DirectoryAccessManager {
17
+ constructor(config = {}, logger = null) {
18
+ this.logger = logger;
19
+ this.config = config;
20
+
21
+ // Default system restrictions (platform-aware from platformUtils)
22
+ this.systemRestrictedPaths = [
23
+ ...getSystemRestrictedPaths(),
24
+ // User sensitive directories (cross-platform)
25
+ path.join(os.homedir(), '.ssh'),
26
+ path.join(os.homedir(), '.aws'),
27
+ path.join(os.homedir(), '.config'),
28
+ path.join(os.homedir(), '.gnupg'),
29
+ // Common package managers and git internals
30
+ 'node_modules/.bin',
31
+ '.git/objects',
32
+ '.git/hooks'
33
+ ];
34
+ }
35
+
36
+ /**
37
+ * Create directory access configuration for an agent
38
+ * @param {Object} options - Access configuration options
39
+ * @returns {Object} Directory access configuration
40
+ */
41
+ createDirectoryAccess(options = {}) {
42
+ const {
43
+ workingDirectory = process.cwd(),
44
+ readOnlyDirectories = [],
45
+ writeEnabledDirectories = [],
46
+ restrictToProject = true,
47
+ allowSystemAccess = false,
48
+ customRestrictions = []
49
+ } = options;
50
+
51
+ // Normalize all paths to absolute
52
+ const workingDir = path.resolve(workingDirectory);
53
+ const readOnlyDirs = readOnlyDirectories.map(dir => this.normalizePath(dir, workingDir));
54
+ const writeEnabledDirs = writeEnabledDirectories.map(dir => this.normalizePath(dir, workingDir));
55
+
56
+ // If restrict to project, ensure working directory is included
57
+ const finalReadOnlyDirs = restrictToProject
58
+ ? [...new Set([...readOnlyDirs, workingDir])]
59
+ : readOnlyDirs;
60
+
61
+ const finalWriteEnabledDirs = restrictToProject
62
+ ? writeEnabledDirs.filter(dir => this.isPathWithinDirectory(dir, workingDir))
63
+ : writeEnabledDirs;
64
+
65
+ return {
66
+ workingDirectory: workingDir,
67
+ readOnlyDirectories: finalReadOnlyDirs,
68
+ writeEnabledDirectories: finalWriteEnabledDirs,
69
+ restrictToProject,
70
+ allowSystemAccess,
71
+ customRestrictions: customRestrictions.map(restriction => path.resolve(restriction)),
72
+ createdAt: new Date().toISOString(),
73
+ version: '1.0'
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Validate if a path can be accessed for reading
79
+ * @param {string} targetPath - Path to validate
80
+ * @param {Object} accessConfig - Directory access configuration
81
+ * @returns {Object} Validation result
82
+ */
83
+ validateReadAccess(targetPath, accessConfig) {
84
+ try {
85
+ const resolvedPath = this.resolvePath(targetPath, accessConfig.workingDirectory);
86
+
87
+ // Check system restrictions first
88
+ if (!accessConfig.allowSystemAccess && this.isSystemRestrictedPath(resolvedPath)) {
89
+ return {
90
+ allowed: false,
91
+ reason: 'System path access denied',
92
+ path: resolvedPath,
93
+ category: 'system_restricted'
94
+ };
95
+ }
96
+
97
+ // Check custom restrictions
98
+ if (this.isCustomRestricted(resolvedPath, accessConfig.customRestrictions)) {
99
+ return {
100
+ allowed: false,
101
+ reason: 'Custom restriction applied',
102
+ path: resolvedPath,
103
+ category: 'custom_restricted'
104
+ };
105
+ }
106
+
107
+ // If restricting to project, ensure path is within allowed boundaries
108
+ if (accessConfig.restrictToProject) {
109
+ // Build list of allowed directories, using workingDirectory as fallback if lists are empty
110
+ const allowedDirs = [
111
+ ...(accessConfig.readOnlyDirectories || []),
112
+ ...(accessConfig.writeEnabledDirectories || [])
113
+ ];
114
+
115
+ // If no explicit directories configured, use workingDirectory as the project scope
116
+ if (allowedDirs.length === 0 && accessConfig.workingDirectory) {
117
+ allowedDirs.push(accessConfig.workingDirectory);
118
+ }
119
+
120
+ const isWithinProject = this.isPathWithinAnyDirectory(resolvedPath, allowedDirs);
121
+
122
+ if (!isWithinProject) {
123
+ return {
124
+ allowed: false,
125
+ reason: 'Path outside project scope',
126
+ path: resolvedPath,
127
+ category: 'project_restricted'
128
+ };
129
+ }
130
+ }
131
+
132
+ // Check if path is within any allowed directory
133
+ const isWithinAllowed = this.isPathWithinAnyDirectory(resolvedPath, [
134
+ ...accessConfig.readOnlyDirectories,
135
+ ...accessConfig.writeEnabledDirectories
136
+ ]);
137
+
138
+ if (!isWithinAllowed && accessConfig.readOnlyDirectories.length > 0) {
139
+ return {
140
+ allowed: false,
141
+ reason: 'Path not in allowed directories',
142
+ path: resolvedPath,
143
+ category: 'directory_restricted'
144
+ };
145
+ }
146
+
147
+ return {
148
+ allowed: true,
149
+ path: resolvedPath,
150
+ category: 'allowed'
151
+ };
152
+
153
+ } catch (error) {
154
+ return {
155
+ allowed: false,
156
+ reason: `Path validation error: ${error.message}`,
157
+ path: targetPath,
158
+ category: 'validation_error'
159
+ };
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Validate if a path can be accessed for writing
165
+ * @param {string} targetPath - Path to validate
166
+ * @param {Object} accessConfig - Directory access configuration
167
+ * @returns {Object} Validation result
168
+ */
169
+ validateWriteAccess(targetPath, accessConfig) {
170
+ // First check read access
171
+ const readResult = this.validateReadAccess(targetPath, accessConfig);
172
+ if (!readResult.allowed) {
173
+ return {
174
+ ...readResult,
175
+ writeAllowed: false
176
+ };
177
+ }
178
+
179
+ const resolvedPath = readResult.path;
180
+
181
+ // Build effective write-enabled directories list
182
+ // If writeEnabledDirectories is empty but we have a workingDirectory,
183
+ // treat the workingDirectory as implicitly write-enabled
184
+ let effectiveWriteEnabled = [...(accessConfig.writeEnabledDirectories || [])];
185
+
186
+ if (effectiveWriteEnabled.length === 0 && accessConfig.workingDirectory) {
187
+ // Fallback: working directory is implicitly write-enabled when no explicit dirs configured
188
+ effectiveWriteEnabled = [accessConfig.workingDirectory];
189
+ this.logger?.debug('No writeEnabledDirectories configured, using workingDirectory as fallback', {
190
+ workingDirectory: accessConfig.workingDirectory
191
+ });
192
+ }
193
+
194
+ // Check if path is within write-enabled directories
195
+ const isWithinWriteEnabled = this.isPathWithinAnyDirectory(
196
+ resolvedPath,
197
+ effectiveWriteEnabled
198
+ );
199
+
200
+ if (!isWithinWriteEnabled) {
201
+ // Check if it's in read-only directories
202
+ const isWithinReadOnly = this.isPathWithinAnyDirectory(
203
+ resolvedPath,
204
+ accessConfig.readOnlyDirectories || []
205
+ );
206
+
207
+ if (isWithinReadOnly) {
208
+ return {
209
+ allowed: false,
210
+ writeAllowed: false,
211
+ reason: 'Path is in read-only directory',
212
+ path: resolvedPath,
213
+ category: 'read_only_restricted'
214
+ };
215
+ }
216
+
217
+ return {
218
+ allowed: false,
219
+ writeAllowed: false,
220
+ reason: 'Path not in write-enabled directories',
221
+ path: resolvedPath,
222
+ category: 'write_restricted'
223
+ };
224
+ }
225
+
226
+ return {
227
+ allowed: true,
228
+ writeAllowed: true,
229
+ path: resolvedPath,
230
+ category: 'write_allowed'
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Get the effective working directory for an agent
236
+ * @param {Object} accessConfig - Directory access configuration
237
+ * @returns {string} Working directory path
238
+ */
239
+ getWorkingDirectory(accessConfig) {
240
+ return accessConfig.workingDirectory || process.cwd();
241
+ }
242
+
243
+ /**
244
+ * List accessible directories for an agent
245
+ * @param {Object} accessConfig - Directory access configuration
246
+ * @returns {Object} Directory listing with permissions
247
+ */
248
+ getAccessibleDirectories(accessConfig) {
249
+ return {
250
+ workingDirectory: accessConfig.workingDirectory,
251
+ readOnly: [...accessConfig.readOnlyDirectories],
252
+ writeEnabled: [...accessConfig.writeEnabledDirectories],
253
+ projectRestricted: accessConfig.restrictToProject,
254
+ systemAccessAllowed: accessConfig.allowSystemAccess,
255
+ totalDirectories: accessConfig.readOnlyDirectories.length + accessConfig.writeEnabledDirectories.length
256
+ };
257
+ }
258
+
259
+ /**
260
+ * Update directory access configuration
261
+ * @param {Object} currentConfig - Current access configuration
262
+ * @param {Object} updates - Updates to apply
263
+ * @returns {Object} Updated configuration
264
+ */
265
+ updateDirectoryAccess(currentConfig, updates) {
266
+ const updatedConfig = { ...currentConfig };
267
+
268
+ if (updates.workingDirectory) {
269
+ updatedConfig.workingDirectory = path.resolve(updates.workingDirectory);
270
+ }
271
+
272
+ if (updates.readOnlyDirectories !== undefined) {
273
+ updatedConfig.readOnlyDirectories = updates.readOnlyDirectories.map(dir =>
274
+ this.normalizePath(dir, updatedConfig.workingDirectory)
275
+ );
276
+ }
277
+
278
+ if (updates.writeEnabledDirectories !== undefined) {
279
+ updatedConfig.writeEnabledDirectories = updates.writeEnabledDirectories.map(dir =>
280
+ this.normalizePath(dir, updatedConfig.workingDirectory)
281
+ );
282
+ }
283
+
284
+ if (updates.restrictToProject !== undefined) {
285
+ updatedConfig.restrictToProject = updates.restrictToProject;
286
+ }
287
+
288
+ if (updates.allowSystemAccess !== undefined) {
289
+ updatedConfig.allowSystemAccess = updates.allowSystemAccess;
290
+ }
291
+
292
+ if (updates.customRestrictions !== undefined) {
293
+ updatedConfig.customRestrictions = updates.customRestrictions.map(restriction =>
294
+ path.resolve(restriction)
295
+ );
296
+ }
297
+
298
+ updatedConfig.version = currentConfig.version || '1.0';
299
+ updatedConfig.updatedAt = new Date().toISOString();
300
+
301
+ return updatedConfig;
302
+ }
303
+
304
+ /**
305
+ * Validate directory access configuration
306
+ * @param {Object} accessConfig - Configuration to validate
307
+ * @returns {Object} Validation result
308
+ */
309
+ validateAccessConfiguration(accessConfig) {
310
+ const errors = [];
311
+ const warnings = [];
312
+
313
+ // Validate working directory exists
314
+ if (!accessConfig.workingDirectory) {
315
+ errors.push('Working directory is required');
316
+ } else {
317
+ // Convert relative paths to absolute paths relative to process.cwd()
318
+ if (!path.isAbsolute(accessConfig.workingDirectory)) {
319
+ accessConfig.workingDirectory = path.resolve(process.cwd(), accessConfig.workingDirectory);
320
+ }
321
+ }
322
+
323
+ // Validate directory arrays
324
+ if (!Array.isArray(accessConfig.readOnlyDirectories)) {
325
+ errors.push('readOnlyDirectories must be an array');
326
+ } else {
327
+ // Convert relative paths to absolute paths
328
+ accessConfig.readOnlyDirectories = accessConfig.readOnlyDirectories.map(dir =>
329
+ path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir)
330
+ );
331
+ }
332
+
333
+ if (!Array.isArray(accessConfig.writeEnabledDirectories)) {
334
+ errors.push('writeEnabledDirectories must be an array');
335
+ } else {
336
+ // Convert relative paths to absolute paths
337
+ accessConfig.writeEnabledDirectories = accessConfig.writeEnabledDirectories.map(dir =>
338
+ path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir)
339
+ );
340
+ }
341
+
342
+ // Check for overlapping directories
343
+ if (accessConfig.readOnlyDirectories && accessConfig.writeEnabledDirectories) {
344
+ const overlapping = this.findOverlappingPaths(
345
+ accessConfig.readOnlyDirectories,
346
+ accessConfig.writeEnabledDirectories
347
+ );
348
+
349
+ if (overlapping.length > 0) {
350
+ warnings.push(`Overlapping directories found: ${overlapping.join(', ')}`);
351
+ }
352
+ }
353
+
354
+ // Check for system path access
355
+ if (accessConfig.allowSystemAccess) {
356
+ warnings.push('System path access is enabled - use with caution');
357
+ }
358
+
359
+ // Validate paths exist (async check would be needed in real implementation)
360
+ const allPaths = [
361
+ ...accessConfig.readOnlyDirectories,
362
+ ...accessConfig.writeEnabledDirectories
363
+ ];
364
+
365
+ for (const dirPath of allPaths) {
366
+ if (!path.isAbsolute(dirPath)) {
367
+ errors.push(`Directory path must be absolute: ${dirPath}`);
368
+ }
369
+ }
370
+
371
+ return {
372
+ valid: errors.length === 0,
373
+ errors,
374
+ warnings,
375
+ summary: {
376
+ readOnlyCount: accessConfig.readOnlyDirectories?.length || 0,
377
+ writeEnabledCount: accessConfig.writeEnabledDirectories?.length || 0,
378
+ restrictToProject: accessConfig.restrictToProject,
379
+ allowSystemAccess: accessConfig.allowSystemAccess
380
+ }
381
+ };
382
+ }
383
+
384
+ /**
385
+ * Create relative path from absolute path within accessible directories
386
+ * @param {string} absolutePath - Absolute path to convert
387
+ * @param {Object} accessConfig - Directory access configuration
388
+ * @returns {string} Relative path or original if not within accessible directories
389
+ */
390
+ createRelativePath(absolutePath, accessConfig) {
391
+ const allDirectories = [
392
+ ...accessConfig.readOnlyDirectories,
393
+ ...accessConfig.writeEnabledDirectories,
394
+ accessConfig.workingDirectory
395
+ ];
396
+
397
+ for (const dir of allDirectories) {
398
+ if (this.isPathWithinDirectory(absolutePath, dir)) {
399
+ return path.relative(dir, absolutePath);
400
+ }
401
+ }
402
+
403
+ return absolutePath;
404
+ }
405
+
406
+ /**
407
+ * Resolve path relative to working directory or as absolute
408
+ * @private
409
+ */
410
+ resolvePath(targetPath, workingDirectory) {
411
+ if (path.isAbsolute(targetPath)) {
412
+ return path.normalize(targetPath);
413
+ }
414
+ return path.resolve(workingDirectory, targetPath);
415
+ }
416
+
417
+ /**
418
+ * Normalize path to absolute, resolving relative to working directory
419
+ * @private
420
+ */
421
+ normalizePath(targetPath, workingDirectory) {
422
+ if (path.isAbsolute(targetPath)) {
423
+ return path.normalize(targetPath);
424
+ }
425
+ return path.resolve(workingDirectory, targetPath);
426
+ }
427
+
428
+ /**
429
+ * Check if path is within a directory
430
+ * Uses case-insensitive comparison on macOS and Windows
431
+ * @private
432
+ */
433
+ isPathWithinDirectory(targetPath, parentDirectory) {
434
+ // macOS (APFS/HFS+) and Windows (NTFS) are case-insensitive
435
+ const caseInsensitive = process.platform === 'darwin' || process.platform === 'win32';
436
+
437
+ // Normalize paths for comparison
438
+ let normalizedTarget = path.normalize(targetPath);
439
+ let normalizedParent = path.normalize(parentDirectory);
440
+
441
+ // Apply case-insensitive comparison if needed
442
+ if (caseInsensitive) {
443
+ normalizedTarget = normalizedTarget.toLowerCase();
444
+ normalizedParent = normalizedParent.toLowerCase();
445
+ }
446
+
447
+ const relative = path.relative(normalizedParent, normalizedTarget);
448
+ return !relative.startsWith('..') && !path.isAbsolute(relative);
449
+ }
450
+
451
+ /**
452
+ * Check if path is within any of the provided directories
453
+ * @private
454
+ */
455
+ isPathWithinAnyDirectory(targetPath, directories) {
456
+ return directories.some(dir => this.isPathWithinDirectory(targetPath, dir));
457
+ }
458
+
459
+ /**
460
+ * Check if path is system restricted
461
+ * Uses case-insensitive comparison on macOS and Windows
462
+ * @private
463
+ */
464
+ isSystemRestrictedPath(targetPath) {
465
+ // macOS (APFS/HFS+) and Windows (NTFS) are case-insensitive
466
+ const caseInsensitive = process.platform === 'darwin' || process.platform === 'win32';
467
+
468
+ const normalizedTarget = caseInsensitive ? targetPath.toLowerCase() : targetPath;
469
+
470
+ return this.systemRestrictedPaths.some(restrictedPath => {
471
+ const normalizedRestricted = caseInsensitive ? restrictedPath.toLowerCase() : restrictedPath;
472
+ return normalizedTarget.startsWith(normalizedRestricted) || normalizedTarget === normalizedRestricted;
473
+ });
474
+ }
475
+
476
+ /**
477
+ * Check if path is custom restricted
478
+ * @private
479
+ */
480
+ isCustomRestricted(targetPath, customRestrictions) {
481
+ if (!customRestrictions || customRestrictions.length === 0) {
482
+ return false;
483
+ }
484
+
485
+ return customRestrictions.some(restriction => {
486
+ return targetPath.startsWith(restriction) || targetPath === restriction;
487
+ });
488
+ }
489
+
490
+ /**
491
+ * Find overlapping paths between two arrays
492
+ * @private
493
+ */
494
+ findOverlappingPaths(paths1, paths2) {
495
+ const overlapping = [];
496
+
497
+ for (const path1 of paths1) {
498
+ for (const path2 of paths2) {
499
+ if (this.isPathWithinDirectory(path1, path2) || this.isPathWithinDirectory(path2, path1)) {
500
+ overlapping.push(`${path1} <-> ${path2}`);
501
+ }
502
+ }
503
+ }
504
+
505
+ return overlapping;
506
+ }
507
+
508
+ /**
509
+ * Get directory access summary for logging/debugging
510
+ * @param {Object} accessConfig - Directory access configuration
511
+ * @returns {Object} Summary object
512
+ */
513
+ getAccessSummary(accessConfig) {
514
+ return {
515
+ workingDirectory: accessConfig.workingDirectory,
516
+ readOnlyCount: accessConfig.readOnlyDirectories.length,
517
+ writeEnabledCount: accessConfig.writeEnabledDirectories.length,
518
+ projectRestricted: accessConfig.restrictToProject,
519
+ systemAccessAllowed: accessConfig.allowSystemAccess,
520
+ customRestrictionsCount: accessConfig.customRestrictions?.length || 0,
521
+ configVersion: accessConfig.version || 'unknown',
522
+ lastUpdated: accessConfig.updatedAt || accessConfig.createdAt
523
+ };
524
+ }
525
+
526
+ /**
527
+ * Create default directory access for project-based agents
528
+ * @param {string} projectDir - Project directory path
529
+ * @returns {Object} Default directory access configuration
530
+ */
531
+ static createProjectDefaults(projectDir) {
532
+ const resolvedProject = path.resolve(projectDir);
533
+
534
+ return {
535
+ workingDirectory: resolvedProject,
536
+ readOnlyDirectories: [resolvedProject],
537
+ writeEnabledDirectories: [resolvedProject],
538
+ restrictToProject: true,
539
+ allowSystemAccess: false,
540
+ customRestrictions: [],
541
+ createdAt: new Date().toISOString(),
542
+ version: '1.0'
543
+ };
544
+ }
545
+
546
+ /**
547
+ * Create permissive directory access (use with caution)
548
+ * @param {string} workingDir - Working directory
549
+ * @returns {Object} Permissive directory access configuration
550
+ */
551
+ static createPermissiveDefaults(workingDir = process.cwd()) {
552
+ return {
553
+ workingDirectory: path.resolve(workingDir),
554
+ readOnlyDirectories: [os.homedir()],
555
+ writeEnabledDirectories: [path.resolve(workingDir)],
556
+ restrictToProject: false,
557
+ allowSystemAccess: false,
558
+ customRestrictions: [],
559
+ createdAt: new Date().toISOString(),
560
+ version: '1.0'
561
+ };
562
+ }
563
+ }
564
+
566
565
  export default DirectoryAccessManager;