onbuzz 3.3.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 (506) hide show
  1. package/LICENSE +267 -0
  2. package/README.md +425 -0
  3. package/bin/cli.js +556 -0
  4. package/bin/loxia-terminal-v2.js +162 -0
  5. package/bin/loxia-terminal.js +90 -0
  6. package/bin/start-with-terminal.js +200 -0
  7. package/node_modules/@isaacs/balanced-match/LICENSE.md +23 -0
  8. package/node_modules/@isaacs/balanced-match/README.md +60 -0
  9. package/node_modules/@isaacs/balanced-match/dist/commonjs/index.d.ts +9 -0
  10. package/node_modules/@isaacs/balanced-match/dist/commonjs/index.d.ts.map +1 -0
  11. package/node_modules/@isaacs/balanced-match/dist/commonjs/index.js +59 -0
  12. package/node_modules/@isaacs/balanced-match/dist/commonjs/index.js.map +1 -0
  13. package/node_modules/@isaacs/balanced-match/dist/commonjs/package.json +3 -0
  14. package/node_modules/@isaacs/balanced-match/dist/esm/index.d.ts +9 -0
  15. package/node_modules/@isaacs/balanced-match/dist/esm/index.d.ts.map +1 -0
  16. package/node_modules/@isaacs/balanced-match/dist/esm/index.js +54 -0
  17. package/node_modules/@isaacs/balanced-match/dist/esm/index.js.map +1 -0
  18. package/node_modules/@isaacs/balanced-match/dist/esm/package.json +3 -0
  19. package/node_modules/@isaacs/balanced-match/package.json +79 -0
  20. package/node_modules/@isaacs/brace-expansion/LICENSE +23 -0
  21. package/node_modules/@isaacs/brace-expansion/README.md +97 -0
  22. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.d.ts +6 -0
  23. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.d.ts.map +1 -0
  24. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js +199 -0
  25. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +1 -0
  26. package/node_modules/@isaacs/brace-expansion/dist/commonjs/package.json +3 -0
  27. package/node_modules/@isaacs/brace-expansion/dist/esm/index.d.ts +6 -0
  28. package/node_modules/@isaacs/brace-expansion/dist/esm/index.d.ts.map +1 -0
  29. package/node_modules/@isaacs/brace-expansion/dist/esm/index.js +195 -0
  30. package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +1 -0
  31. package/node_modules/@isaacs/brace-expansion/dist/esm/package.json +3 -0
  32. package/node_modules/@isaacs/brace-expansion/package.json +60 -0
  33. package/node_modules/glob/LICENSE.md +63 -0
  34. package/node_modules/glob/README.md +1177 -0
  35. package/node_modules/glob/dist/commonjs/glob.d.ts +388 -0
  36. package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -0
  37. package/node_modules/glob/dist/commonjs/glob.js +247 -0
  38. package/node_modules/glob/dist/commonjs/glob.js.map +1 -0
  39. package/node_modules/glob/dist/commonjs/has-magic.d.ts +14 -0
  40. package/node_modules/glob/dist/commonjs/has-magic.d.ts.map +1 -0
  41. package/node_modules/glob/dist/commonjs/has-magic.js +27 -0
  42. package/node_modules/glob/dist/commonjs/has-magic.js.map +1 -0
  43. package/node_modules/glob/dist/commonjs/ignore.d.ts +24 -0
  44. package/node_modules/glob/dist/commonjs/ignore.d.ts.map +1 -0
  45. package/node_modules/glob/dist/commonjs/ignore.js +119 -0
  46. package/node_modules/glob/dist/commonjs/ignore.js.map +1 -0
  47. package/node_modules/glob/dist/commonjs/index.d.ts +97 -0
  48. package/node_modules/glob/dist/commonjs/index.d.ts.map +1 -0
  49. package/node_modules/glob/dist/commonjs/index.js +68 -0
  50. package/node_modules/glob/dist/commonjs/index.js.map +1 -0
  51. package/node_modules/glob/dist/commonjs/index.min.js +4 -0
  52. package/node_modules/glob/dist/commonjs/index.min.js.map +7 -0
  53. package/node_modules/glob/dist/commonjs/package.json +3 -0
  54. package/node_modules/glob/dist/commonjs/pattern.d.ts +76 -0
  55. package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -0
  56. package/node_modules/glob/dist/commonjs/pattern.js +219 -0
  57. package/node_modules/glob/dist/commonjs/pattern.js.map +1 -0
  58. package/node_modules/glob/dist/commonjs/processor.d.ts +59 -0
  59. package/node_modules/glob/dist/commonjs/processor.d.ts.map +1 -0
  60. package/node_modules/glob/dist/commonjs/processor.js +301 -0
  61. package/node_modules/glob/dist/commonjs/processor.js.map +1 -0
  62. package/node_modules/glob/dist/commonjs/walker.d.ts +97 -0
  63. package/node_modules/glob/dist/commonjs/walker.d.ts.map +1 -0
  64. package/node_modules/glob/dist/commonjs/walker.js +387 -0
  65. package/node_modules/glob/dist/commonjs/walker.js.map +1 -0
  66. package/node_modules/glob/dist/esm/glob.d.ts +388 -0
  67. package/node_modules/glob/dist/esm/glob.d.ts.map +1 -0
  68. package/node_modules/glob/dist/esm/glob.js +243 -0
  69. package/node_modules/glob/dist/esm/glob.js.map +1 -0
  70. package/node_modules/glob/dist/esm/has-magic.d.ts +14 -0
  71. package/node_modules/glob/dist/esm/has-magic.d.ts.map +1 -0
  72. package/node_modules/glob/dist/esm/has-magic.js +23 -0
  73. package/node_modules/glob/dist/esm/has-magic.js.map +1 -0
  74. package/node_modules/glob/dist/esm/ignore.d.ts +24 -0
  75. package/node_modules/glob/dist/esm/ignore.d.ts.map +1 -0
  76. package/node_modules/glob/dist/esm/ignore.js +115 -0
  77. package/node_modules/glob/dist/esm/ignore.js.map +1 -0
  78. package/node_modules/glob/dist/esm/index.d.ts +97 -0
  79. package/node_modules/glob/dist/esm/index.d.ts.map +1 -0
  80. package/node_modules/glob/dist/esm/index.js +55 -0
  81. package/node_modules/glob/dist/esm/index.js.map +1 -0
  82. package/node_modules/glob/dist/esm/index.min.js +4 -0
  83. package/node_modules/glob/dist/esm/index.min.js.map +7 -0
  84. package/node_modules/glob/dist/esm/package.json +3 -0
  85. package/node_modules/glob/dist/esm/pattern.d.ts +76 -0
  86. package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -0
  87. package/node_modules/glob/dist/esm/pattern.js +215 -0
  88. package/node_modules/glob/dist/esm/pattern.js.map +1 -0
  89. package/node_modules/glob/dist/esm/processor.d.ts +59 -0
  90. package/node_modules/glob/dist/esm/processor.d.ts.map +1 -0
  91. package/node_modules/glob/dist/esm/processor.js +294 -0
  92. package/node_modules/glob/dist/esm/processor.js.map +1 -0
  93. package/node_modules/glob/dist/esm/walker.d.ts +97 -0
  94. package/node_modules/glob/dist/esm/walker.d.ts.map +1 -0
  95. package/node_modules/glob/dist/esm/walker.js +381 -0
  96. package/node_modules/glob/dist/esm/walker.js.map +1 -0
  97. package/node_modules/glob/node_modules/minimatch/LICENSE.md +55 -0
  98. package/node_modules/glob/node_modules/minimatch/README.md +453 -0
  99. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +2 -0
  100. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -0
  101. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
  102. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -0
  103. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +20 -0
  104. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -0
  105. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +591 -0
  106. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -0
  107. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +8 -0
  108. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -0
  109. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +152 -0
  110. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -0
  111. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +15 -0
  112. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -0
  113. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +30 -0
  114. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -0
  115. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +94 -0
  116. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -0
  117. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +1029 -0
  118. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -0
  119. package/node_modules/glob/node_modules/minimatch/dist/commonjs/package.json +3 -0
  120. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +22 -0
  121. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -0
  122. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +38 -0
  123. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -0
  124. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +2 -0
  125. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -0
  126. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
  127. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -0
  128. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +20 -0
  129. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -0
  130. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +587 -0
  131. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -0
  132. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts +8 -0
  133. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -0
  134. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +148 -0
  135. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -0
  136. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +15 -0
  137. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -0
  138. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +26 -0
  139. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -0
  140. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +94 -0
  141. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -0
  142. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +1016 -0
  143. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -0
  144. package/node_modules/glob/node_modules/minimatch/dist/esm/package.json +3 -0
  145. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +22 -0
  146. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -0
  147. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +34 -0
  148. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -0
  149. package/node_modules/glob/node_modules/minimatch/package.json +67 -0
  150. package/node_modules/glob/package.json +101 -0
  151. package/node_modules/minipass/LICENSE +15 -0
  152. package/node_modules/minipass/README.md +825 -0
  153. package/node_modules/minipass/dist/commonjs/index.d.ts +549 -0
  154. package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -0
  155. package/node_modules/minipass/dist/commonjs/index.js +1028 -0
  156. package/node_modules/minipass/dist/commonjs/index.js.map +1 -0
  157. package/node_modules/minipass/dist/commonjs/package.json +3 -0
  158. package/node_modules/minipass/dist/esm/index.d.ts +549 -0
  159. package/node_modules/minipass/dist/esm/index.d.ts.map +1 -0
  160. package/node_modules/minipass/dist/esm/index.js +1018 -0
  161. package/node_modules/minipass/dist/esm/index.js.map +1 -0
  162. package/node_modules/minipass/dist/esm/package.json +3 -0
  163. package/node_modules/minipass/package.json +82 -0
  164. package/node_modules/package-json-from-dist/LICENSE.md +63 -0
  165. package/node_modules/package-json-from-dist/README.md +110 -0
  166. package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts +89 -0
  167. package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts.map +1 -0
  168. package/node_modules/package-json-from-dist/dist/commonjs/index.js +134 -0
  169. package/node_modules/package-json-from-dist/dist/commonjs/index.js.map +1 -0
  170. package/node_modules/package-json-from-dist/dist/commonjs/package.json +3 -0
  171. package/node_modules/package-json-from-dist/dist/esm/index.d.ts +89 -0
  172. package/node_modules/package-json-from-dist/dist/esm/index.d.ts.map +1 -0
  173. package/node_modules/package-json-from-dist/dist/esm/index.js +129 -0
  174. package/node_modules/package-json-from-dist/dist/esm/index.js.map +1 -0
  175. package/node_modules/package-json-from-dist/dist/esm/package.json +3 -0
  176. package/node_modules/package-json-from-dist/package.json +68 -0
  177. package/node_modules/path-scurry/LICENSE.md +55 -0
  178. package/node_modules/path-scurry/README.md +636 -0
  179. package/node_modules/path-scurry/dist/commonjs/index.d.ts +1115 -0
  180. package/node_modules/path-scurry/dist/commonjs/index.d.ts.map +1 -0
  181. package/node_modules/path-scurry/dist/commonjs/index.js +2018 -0
  182. package/node_modules/path-scurry/dist/commonjs/index.js.map +1 -0
  183. package/node_modules/path-scurry/dist/commonjs/package.json +3 -0
  184. package/node_modules/path-scurry/dist/esm/index.d.ts +1115 -0
  185. package/node_modules/path-scurry/dist/esm/index.d.ts.map +1 -0
  186. package/node_modules/path-scurry/dist/esm/index.js +1983 -0
  187. package/node_modules/path-scurry/dist/esm/index.js.map +1 -0
  188. package/node_modules/path-scurry/dist/esm/package.json +3 -0
  189. package/node_modules/path-scurry/node_modules/lru-cache/LICENSE.md +55 -0
  190. package/node_modules/path-scurry/node_modules/lru-cache/README.md +383 -0
  191. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +1323 -0
  192. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -0
  193. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +1589 -0
  194. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -0
  195. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +2 -0
  196. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +7 -0
  197. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/package.json +3 -0
  198. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +1323 -0
  199. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -0
  200. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +1585 -0
  201. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -0
  202. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +2 -0
  203. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +7 -0
  204. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/package.json +3 -0
  205. package/node_modules/path-scurry/node_modules/lru-cache/package.json +101 -0
  206. package/node_modules/path-scurry/package.json +88 -0
  207. package/node_modules/rimraf/LICENSE.md +55 -0
  208. package/node_modules/rimraf/README.md +226 -0
  209. package/node_modules/rimraf/dist/commonjs/default-tmp.d.ts +3 -0
  210. package/node_modules/rimraf/dist/commonjs/default-tmp.d.ts.map +1 -0
  211. package/node_modules/rimraf/dist/commonjs/default-tmp.js +58 -0
  212. package/node_modules/rimraf/dist/commonjs/default-tmp.js.map +1 -0
  213. package/node_modules/rimraf/dist/commonjs/error.d.ts +6 -0
  214. package/node_modules/rimraf/dist/commonjs/error.d.ts.map +1 -0
  215. package/node_modules/rimraf/dist/commonjs/error.js +10 -0
  216. package/node_modules/rimraf/dist/commonjs/error.js.map +1 -0
  217. package/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts +3 -0
  218. package/node_modules/rimraf/dist/commonjs/fix-eperm.d.ts.map +1 -0
  219. package/node_modules/rimraf/dist/commonjs/fix-eperm.js +38 -0
  220. package/node_modules/rimraf/dist/commonjs/fix-eperm.js.map +1 -0
  221. package/node_modules/rimraf/dist/commonjs/fs.d.ts +15 -0
  222. package/node_modules/rimraf/dist/commonjs/fs.d.ts.map +1 -0
  223. package/node_modules/rimraf/dist/commonjs/fs.js +33 -0
  224. package/node_modules/rimraf/dist/commonjs/fs.js.map +1 -0
  225. package/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts +3 -0
  226. package/node_modules/rimraf/dist/commonjs/ignore-enoent.d.ts.map +1 -0
  227. package/node_modules/rimraf/dist/commonjs/ignore-enoent.js +24 -0
  228. package/node_modules/rimraf/dist/commonjs/ignore-enoent.js.map +1 -0
  229. package/node_modules/rimraf/dist/commonjs/index.d.ts +50 -0
  230. package/node_modules/rimraf/dist/commonjs/index.d.ts.map +1 -0
  231. package/node_modules/rimraf/dist/commonjs/index.js +78 -0
  232. package/node_modules/rimraf/dist/commonjs/index.js.map +1 -0
  233. package/node_modules/rimraf/dist/commonjs/opt-arg.d.ts +34 -0
  234. package/node_modules/rimraf/dist/commonjs/opt-arg.d.ts.map +1 -0
  235. package/node_modules/rimraf/dist/commonjs/opt-arg.js +53 -0
  236. package/node_modules/rimraf/dist/commonjs/opt-arg.js.map +1 -0
  237. package/node_modules/rimraf/dist/commonjs/package.json +3 -0
  238. package/node_modules/rimraf/dist/commonjs/path-arg.d.ts +4 -0
  239. package/node_modules/rimraf/dist/commonjs/path-arg.d.ts.map +1 -0
  240. package/node_modules/rimraf/dist/commonjs/path-arg.js +48 -0
  241. package/node_modules/rimraf/dist/commonjs/path-arg.js.map +1 -0
  242. package/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts +3 -0
  243. package/node_modules/rimraf/dist/commonjs/readdir-or-error.d.ts.map +1 -0
  244. package/node_modules/rimraf/dist/commonjs/readdir-or-error.js +19 -0
  245. package/node_modules/rimraf/dist/commonjs/readdir-or-error.js.map +1 -0
  246. package/node_modules/rimraf/dist/commonjs/retry-busy.d.ts +8 -0
  247. package/node_modules/rimraf/dist/commonjs/retry-busy.d.ts.map +1 -0
  248. package/node_modules/rimraf/dist/commonjs/retry-busy.js +65 -0
  249. package/node_modules/rimraf/dist/commonjs/retry-busy.js.map +1 -0
  250. package/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts +3 -0
  251. package/node_modules/rimraf/dist/commonjs/rimraf-manual.d.ts.map +1 -0
  252. package/node_modules/rimraf/dist/commonjs/rimraf-manual.js +8 -0
  253. package/node_modules/rimraf/dist/commonjs/rimraf-manual.js.map +1 -0
  254. package/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts +4 -0
  255. package/node_modules/rimraf/dist/commonjs/rimraf-move-remove.d.ts.map +1 -0
  256. package/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js +138 -0
  257. package/node_modules/rimraf/dist/commonjs/rimraf-move-remove.js.map +1 -0
  258. package/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts +4 -0
  259. package/node_modules/rimraf/dist/commonjs/rimraf-native.d.ts.map +1 -0
  260. package/node_modules/rimraf/dist/commonjs/rimraf-native.js +24 -0
  261. package/node_modules/rimraf/dist/commonjs/rimraf-native.js.map +1 -0
  262. package/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts +4 -0
  263. package/node_modules/rimraf/dist/commonjs/rimraf-posix.d.ts.map +1 -0
  264. package/node_modules/rimraf/dist/commonjs/rimraf-posix.js +103 -0
  265. package/node_modules/rimraf/dist/commonjs/rimraf-posix.js.map +1 -0
  266. package/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts +4 -0
  267. package/node_modules/rimraf/dist/commonjs/rimraf-windows.d.ts.map +1 -0
  268. package/node_modules/rimraf/dist/commonjs/rimraf-windows.js +159 -0
  269. package/node_modules/rimraf/dist/commonjs/rimraf-windows.js.map +1 -0
  270. package/node_modules/rimraf/dist/commonjs/use-native.d.ts +4 -0
  271. package/node_modules/rimraf/dist/commonjs/use-native.d.ts.map +1 -0
  272. package/node_modules/rimraf/dist/commonjs/use-native.js +18 -0
  273. package/node_modules/rimraf/dist/commonjs/use-native.js.map +1 -0
  274. package/node_modules/rimraf/dist/esm/bin.d.mts +3 -0
  275. package/node_modules/rimraf/dist/esm/bin.d.mts.map +1 -0
  276. package/node_modules/rimraf/dist/esm/bin.mjs +250 -0
  277. package/node_modules/rimraf/dist/esm/bin.mjs.map +1 -0
  278. package/node_modules/rimraf/dist/esm/default-tmp.d.ts +3 -0
  279. package/node_modules/rimraf/dist/esm/default-tmp.d.ts.map +1 -0
  280. package/node_modules/rimraf/dist/esm/default-tmp.js +55 -0
  281. package/node_modules/rimraf/dist/esm/default-tmp.js.map +1 -0
  282. package/node_modules/rimraf/dist/esm/error.d.ts +6 -0
  283. package/node_modules/rimraf/dist/esm/error.d.ts.map +1 -0
  284. package/node_modules/rimraf/dist/esm/error.js +5 -0
  285. package/node_modules/rimraf/dist/esm/error.js.map +1 -0
  286. package/node_modules/rimraf/dist/esm/fix-eperm.d.ts +3 -0
  287. package/node_modules/rimraf/dist/esm/fix-eperm.d.ts.map +1 -0
  288. package/node_modules/rimraf/dist/esm/fix-eperm.js +33 -0
  289. package/node_modules/rimraf/dist/esm/fix-eperm.js.map +1 -0
  290. package/node_modules/rimraf/dist/esm/fs.d.ts +15 -0
  291. package/node_modules/rimraf/dist/esm/fs.d.ts.map +1 -0
  292. package/node_modules/rimraf/dist/esm/fs.js +18 -0
  293. package/node_modules/rimraf/dist/esm/fs.js.map +1 -0
  294. package/node_modules/rimraf/dist/esm/ignore-enoent.d.ts +3 -0
  295. package/node_modules/rimraf/dist/esm/ignore-enoent.d.ts.map +1 -0
  296. package/node_modules/rimraf/dist/esm/ignore-enoent.js +19 -0
  297. package/node_modules/rimraf/dist/esm/ignore-enoent.js.map +1 -0
  298. package/node_modules/rimraf/dist/esm/index.d.ts +50 -0
  299. package/node_modules/rimraf/dist/esm/index.d.ts.map +1 -0
  300. package/node_modules/rimraf/dist/esm/index.js +70 -0
  301. package/node_modules/rimraf/dist/esm/index.js.map +1 -0
  302. package/node_modules/rimraf/dist/esm/opt-arg.d.ts +34 -0
  303. package/node_modules/rimraf/dist/esm/opt-arg.d.ts.map +1 -0
  304. package/node_modules/rimraf/dist/esm/opt-arg.js +46 -0
  305. package/node_modules/rimraf/dist/esm/opt-arg.js.map +1 -0
  306. package/node_modules/rimraf/dist/esm/package.json +3 -0
  307. package/node_modules/rimraf/dist/esm/path-arg.d.ts +4 -0
  308. package/node_modules/rimraf/dist/esm/path-arg.d.ts.map +1 -0
  309. package/node_modules/rimraf/dist/esm/path-arg.js +46 -0
  310. package/node_modules/rimraf/dist/esm/path-arg.js.map +1 -0
  311. package/node_modules/rimraf/dist/esm/readdir-or-error.d.ts +3 -0
  312. package/node_modules/rimraf/dist/esm/readdir-or-error.d.ts.map +1 -0
  313. package/node_modules/rimraf/dist/esm/readdir-or-error.js +14 -0
  314. package/node_modules/rimraf/dist/esm/readdir-or-error.js.map +1 -0
  315. package/node_modules/rimraf/dist/esm/retry-busy.d.ts +8 -0
  316. package/node_modules/rimraf/dist/esm/retry-busy.d.ts.map +1 -0
  317. package/node_modules/rimraf/dist/esm/retry-busy.js +60 -0
  318. package/node_modules/rimraf/dist/esm/retry-busy.js.map +1 -0
  319. package/node_modules/rimraf/dist/esm/rimraf-manual.d.ts +3 -0
  320. package/node_modules/rimraf/dist/esm/rimraf-manual.d.ts.map +1 -0
  321. package/node_modules/rimraf/dist/esm/rimraf-manual.js +5 -0
  322. package/node_modules/rimraf/dist/esm/rimraf-manual.js.map +1 -0
  323. package/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts +4 -0
  324. package/node_modules/rimraf/dist/esm/rimraf-move-remove.d.ts.map +1 -0
  325. package/node_modules/rimraf/dist/esm/rimraf-move-remove.js +133 -0
  326. package/node_modules/rimraf/dist/esm/rimraf-move-remove.js.map +1 -0
  327. package/node_modules/rimraf/dist/esm/rimraf-native.d.ts +4 -0
  328. package/node_modules/rimraf/dist/esm/rimraf-native.d.ts.map +1 -0
  329. package/node_modules/rimraf/dist/esm/rimraf-native.js +19 -0
  330. package/node_modules/rimraf/dist/esm/rimraf-native.js.map +1 -0
  331. package/node_modules/rimraf/dist/esm/rimraf-posix.d.ts +4 -0
  332. package/node_modules/rimraf/dist/esm/rimraf-posix.d.ts.map +1 -0
  333. package/node_modules/rimraf/dist/esm/rimraf-posix.js +98 -0
  334. package/node_modules/rimraf/dist/esm/rimraf-posix.js.map +1 -0
  335. package/node_modules/rimraf/dist/esm/rimraf-windows.d.ts +4 -0
  336. package/node_modules/rimraf/dist/esm/rimraf-windows.d.ts.map +1 -0
  337. package/node_modules/rimraf/dist/esm/rimraf-windows.js +154 -0
  338. package/node_modules/rimraf/dist/esm/rimraf-windows.js.map +1 -0
  339. package/node_modules/rimraf/dist/esm/use-native.d.ts +4 -0
  340. package/node_modules/rimraf/dist/esm/use-native.d.ts.map +1 -0
  341. package/node_modules/rimraf/dist/esm/use-native.js +15 -0
  342. package/node_modules/rimraf/dist/esm/use-native.js.map +1 -0
  343. package/node_modules/rimraf/package.json +92 -0
  344. package/package.json +152 -0
  345. package/scripts/install-scanners.js +258 -0
  346. package/scripts/watchdog.js +147 -0
  347. package/src/analyzers/CSSAnalyzer.js +297 -0
  348. package/src/analyzers/ConfigValidator.js +690 -0
  349. package/src/analyzers/ESLintAnalyzer.js +320 -0
  350. package/src/analyzers/JavaScriptAnalyzer.js +261 -0
  351. package/src/analyzers/PrettierFormatter.js +247 -0
  352. package/src/analyzers/PythonAnalyzer.js +283 -0
  353. package/src/analyzers/SecurityAnalyzer.js +729 -0
  354. package/src/analyzers/SparrowAnalyzer.js +341 -0
  355. package/src/analyzers/TypeScriptAnalyzer.js +247 -0
  356. package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
  357. package/src/analyzers/codeCloneDetector/detector.js +250 -0
  358. package/src/analyzers/codeCloneDetector/index.js +192 -0
  359. package/src/analyzers/codeCloneDetector/parser.js +199 -0
  360. package/src/analyzers/codeCloneDetector/reporter.js +148 -0
  361. package/src/analyzers/codeCloneDetector/scanner.js +88 -0
  362. package/src/core/agentPool.js +1957 -0
  363. package/src/core/agentScheduler.js +3212 -0
  364. package/src/core/contextManager.js +709 -0
  365. package/src/core/flowExecutor.js +928 -0
  366. package/src/core/messageProcessor.js +808 -0
  367. package/src/core/orchestrator.js +584 -0
  368. package/src/core/stateManager.js +1500 -0
  369. package/src/index.js +972 -0
  370. package/src/interfaces/cli.js +553 -0
  371. package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +208 -0
  372. package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +236 -0
  373. package/src/interfaces/terminal/__tests__/smoke/agents.test.js +138 -0
  374. package/src/interfaces/terminal/__tests__/smoke/components.test.js +137 -0
  375. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +350 -0
  376. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -0
  377. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +332 -0
  378. package/src/interfaces/terminal/__tests__/smoke/messages.test.js +256 -0
  379. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +388 -0
  380. package/src/interfaces/terminal/api/apiClient.js +299 -0
  381. package/src/interfaces/terminal/api/messageRouter.js +262 -0
  382. package/src/interfaces/terminal/api/session.js +266 -0
  383. package/src/interfaces/terminal/api/websocket.js +497 -0
  384. package/src/interfaces/terminal/components/AgentCreator.js +705 -0
  385. package/src/interfaces/terminal/components/AgentEditor.js +678 -0
  386. package/src/interfaces/terminal/components/AgentSwitcher.js +330 -0
  387. package/src/interfaces/terminal/components/ErrorBoundary.js +92 -0
  388. package/src/interfaces/terminal/components/ErrorPanel.js +264 -0
  389. package/src/interfaces/terminal/components/Header.js +28 -0
  390. package/src/interfaces/terminal/components/HelpPanel.js +231 -0
  391. package/src/interfaces/terminal/components/InputBox.js +118 -0
  392. package/src/interfaces/terminal/components/Layout.js +603 -0
  393. package/src/interfaces/terminal/components/LoadingSpinner.js +71 -0
  394. package/src/interfaces/terminal/components/MessageList.js +281 -0
  395. package/src/interfaces/terminal/components/MultilineTextInput.js +251 -0
  396. package/src/interfaces/terminal/components/SearchPanel.js +265 -0
  397. package/src/interfaces/terminal/components/SettingsPanel.js +415 -0
  398. package/src/interfaces/terminal/components/StatusBar.js +65 -0
  399. package/src/interfaces/terminal/components/TextInput.js +127 -0
  400. package/src/interfaces/terminal/config/agentEditorConstants.js +227 -0
  401. package/src/interfaces/terminal/config/constants.js +393 -0
  402. package/src/interfaces/terminal/index.js +168 -0
  403. package/src/interfaces/terminal/state/useAgentControl.js +496 -0
  404. package/src/interfaces/terminal/state/useAgents.js +537 -0
  405. package/src/interfaces/terminal/state/useConnection.js +444 -0
  406. package/src/interfaces/terminal/state/useMessages.js +630 -0
  407. package/src/interfaces/terminal/state/useTools.js +554 -0
  408. package/src/interfaces/terminal/utils/debugLogger.js +44 -0
  409. package/src/interfaces/terminal/utils/settingsStorage.js +232 -0
  410. package/src/interfaces/terminal/utils/theme.js +85 -0
  411. package/src/interfaces/webServer.js +5457 -0
  412. package/src/modules/fileExplorer/controller.js +413 -0
  413. package/src/modules/fileExplorer/index.js +37 -0
  414. package/src/modules/fileExplorer/middleware.js +92 -0
  415. package/src/modules/fileExplorer/routes.js +158 -0
  416. package/src/modules/fileExplorer/types.js +44 -0
  417. package/src/services/agentActivityService.js +399 -0
  418. package/src/services/aiService.js +2618 -0
  419. package/src/services/apiKeyManager.js +334 -0
  420. package/src/services/benchmarkService.js +196 -0
  421. package/src/services/budgetService.js +565 -0
  422. package/src/services/contextInjectionService.js +268 -0
  423. package/src/services/conversationCompactionService.js +1103 -0
  424. package/src/services/credentialVault.js +685 -0
  425. package/src/services/errorHandler.js +810 -0
  426. package/src/services/fileAttachmentService.js +547 -0
  427. package/src/services/flowContextService.js +189 -0
  428. package/src/services/memoryService.js +521 -0
  429. package/src/services/modelRouterService.js +365 -0
  430. package/src/services/modelsService.js +323 -0
  431. package/src/services/ollamaService.js +452 -0
  432. package/src/services/portRegistry.js +336 -0
  433. package/src/services/portTracker.js +223 -0
  434. package/src/services/projectDetector.js +404 -0
  435. package/src/services/promptService.js +372 -0
  436. package/src/services/qualityInspector.js +796 -0
  437. package/src/services/scheduleService.js +725 -0
  438. package/src/services/serviceRegistry.js +386 -0
  439. package/src/services/skillsService.js +486 -0
  440. package/src/services/telegramService.js +920 -0
  441. package/src/services/tokenCountingService.js +316 -0
  442. package/src/services/visualEditorBridge.js +1033 -0
  443. package/src/services/visualEditorServer.js +1727 -0
  444. package/src/services/whatsappService.js +663 -0
  445. package/src/tools/__tests__/webTool.e2e.test.js +569 -0
  446. package/src/tools/__tests__/webTool.unit.test.js +195 -0
  447. package/src/tools/agentCommunicationTool.js +1343 -0
  448. package/src/tools/agentDelayTool.js +498 -0
  449. package/src/tools/asyncToolManager.js +604 -0
  450. package/src/tools/baseTool.js +887 -0
  451. package/src/tools/browserTool.js +897 -0
  452. package/src/tools/cloneDetectionTool.js +581 -0
  453. package/src/tools/codeMapTool.js +857 -0
  454. package/src/tools/dependencyResolverTool.js +1212 -0
  455. package/src/tools/docxTool.js +623 -0
  456. package/src/tools/excelTool.js +636 -0
  457. package/src/tools/fileContentReplaceTool.js +840 -0
  458. package/src/tools/fileTreeTool.js +833 -0
  459. package/src/tools/filesystemTool.js +1217 -0
  460. package/src/tools/helpTool.js +198 -0
  461. package/src/tools/imageTool.js +1034 -0
  462. package/src/tools/importAnalyzerTool.js +1056 -0
  463. package/src/tools/jobDoneTool.js +388 -0
  464. package/src/tools/memoryTool.js +554 -0
  465. package/src/tools/pdfTool.js +627 -0
  466. package/src/tools/seekTool.js +883 -0
  467. package/src/tools/skillsTool.js +276 -0
  468. package/src/tools/staticAnalysisTool.js +2146 -0
  469. package/src/tools/taskManagerTool.js +2836 -0
  470. package/src/tools/terminalTool.js +2486 -0
  471. package/src/tools/userPromptTool.js +474 -0
  472. package/src/tools/videoTool.js +1139 -0
  473. package/src/tools/visionTool.js +507 -0
  474. package/src/tools/visualEditorTool.js +1175 -0
  475. package/src/tools/webTool.js +3114 -0
  476. package/src/tools/whatsappTool.js +457 -0
  477. package/src/types/agent.js +519 -0
  478. package/src/types/contextReference.js +972 -0
  479. package/src/types/conversation.js +730 -0
  480. package/src/types/toolCommand.js +747 -0
  481. package/src/utilities/attachmentValidator.js +288 -0
  482. package/src/utilities/browserStealth.js +630 -0
  483. package/src/utilities/configManager.js +618 -0
  484. package/src/utilities/constants.js +870 -0
  485. package/src/utilities/directoryAccessManager.js +566 -0
  486. package/src/utilities/fileProcessor.js +307 -0
  487. package/src/utilities/humanBehavior.js +453 -0
  488. package/src/utilities/jsonRepair.js +242 -0
  489. package/src/utilities/logger.js +436 -0
  490. package/src/utilities/platformUtils.js +255 -0
  491. package/src/utilities/platformUtils.test.js +98 -0
  492. package/src/utilities/stealthConstants.js +377 -0
  493. package/src/utilities/structuredFileValidator.js +699 -0
  494. package/src/utilities/tagParser.js +878 -0
  495. package/src/utilities/toolConstants.js +415 -0
  496. package/src/utilities/userDataDir.js +300 -0
  497. package/web-ui/build/brands/autopilot/favicon.svg +1 -0
  498. package/web-ui/build/brands/autopilot/logo.webp +0 -0
  499. package/web-ui/build/brands/onbuzz/favicon.svg +1 -0
  500. package/web-ui/build/brands/onbuzz/logo-text.webp +0 -0
  501. package/web-ui/build/brands/onbuzz/logo.webp +0 -0
  502. package/web-ui/build/index.html +15 -0
  503. package/web-ui/build/logo.png +0 -0
  504. package/web-ui/build/logo2.png +0 -0
  505. package/web-ui/build/static/index-SmQFfvBs.js +746 -0
  506. package/web-ui/build/static/index-V2ySwjHp.css +1 -0
@@ -0,0 +1,1500 @@
1
+ /**
2
+ * StateManager - Handles state persistence, recovery, and project state management
3
+ *
4
+ * Purpose:
5
+ * - Project state persistence and recovery
6
+ * - Agent state management across sessions
7
+ * - Multi-model conversation state handling
8
+ * - Context reference state management
9
+ * - Session recovery and resume functionality
10
+ *
11
+ * IMPORTANT: State is now stored in a platform-appropriate user data directory
12
+ * that persists across npm package updates. See userDataDir.js for details.
13
+ */
14
+
15
+ import { promises as fs } from 'fs';
16
+ import path from 'path';
17
+ import { getUserDataPaths, ensureUserDataDirs } from '../utilities/userDataDir.js';
18
+
19
+ class StateManager {
20
+ constructor(config, logger) {
21
+ this.config = config;
22
+ this.logger = logger;
23
+
24
+ // UPDATED: Use persistent user data directory instead of relative path
25
+ // This ensures data survives npm package updates
26
+ const userPaths = getUserDataPaths();
27
+ this.stateDirectory = userPaths.state;
28
+ this.userDataPaths = userPaths;
29
+
30
+ // Legacy: Keep for backwards compatibility detection
31
+ this.legacyStateDirectory = config.system?.stateDirectory || '.loxia-state';
32
+ this.stateVersion = '1.0.0';
33
+
34
+ // State file paths
35
+ this.stateFiles = {
36
+ projectState: 'project-state.json',
37
+ agentIndex: 'agent-index.json',
38
+ teamIndex: 'team-index.json',
39
+ flowIndex: 'flow-index.json',
40
+ flowRunIndex: 'flow-run-index.json',
41
+ conversationIndex: 'conversation-index.json',
42
+ lastSession: 'last-session.json',
43
+ contextReferences: 'context-references.json',
44
+ asyncOperations: 'operations/async-operations.json',
45
+ pausedAgents: 'operations/paused-agents.json',
46
+ toolHistory: 'operations/tool-history.json',
47
+ modelRouterCache: 'models/model-router-cache.json',
48
+ errorRecoveryLog: 'models/error-recovery-log.json'
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Get the state directory path
54
+ * UPDATED: Now returns the user data directory (absolute path)
55
+ * The projectDir parameter is kept for API compatibility but is ignored
56
+ * @param {string} projectDir - Ignored, kept for compatibility
57
+ * @returns {string} Absolute path to state directory
58
+ */
59
+ getStateDir(projectDir) {
60
+ // Always use the persistent user data directory
61
+ return this.stateDirectory;
62
+ }
63
+
64
+ /**
65
+ * Get the agents subdirectory path
66
+ * @returns {string} Absolute path to agents directory
67
+ */
68
+ getAgentsDir() {
69
+ return this.userDataPaths.agents;
70
+ }
71
+
72
+ /**
73
+ * Initialize state directory structure
74
+ * @param {string} projectDir - Project directory path (now ignored, uses user data dir)
75
+ * @returns {Promise<void>}
76
+ */
77
+ async initializeStateDirectory(projectDir) {
78
+ // UPDATED: Use persistent user data directory instead of project-relative path
79
+ // The projectDir parameter is kept for API compatibility but now ignored
80
+ try {
81
+ // Use the centralized utility to create all necessary directories
82
+ const paths = await ensureUserDataDirs();
83
+
84
+ this.logger.info(`State directory initialized in user data location`, {
85
+ stateDir: paths.state,
86
+ platform: process.platform
87
+ });
88
+
89
+ } catch (error) {
90
+ this.logger.error(`Failed to initialize state directory: ${error.message}`);
91
+ throw error;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Resume project from saved state
97
+ * @param {string} projectDir - Project directory path
98
+ * @returns {Promise<Object>} Resumed project state
99
+ */
100
+ async resumeProject(projectDir) {
101
+ try {
102
+ await this.initializeStateDirectory(projectDir);
103
+
104
+ // Load project state
105
+ const projectState = await this.loadProjectState(projectDir);
106
+ const agentIndex = await this.loadAgentIndex(projectDir);
107
+
108
+ // Restore agents with multi-model conversations
109
+ const restoredAgents = [];
110
+ for (const [agentId, agentInfo] of Object.entries(agentIndex)) {
111
+ try {
112
+ const agent = await this.restoreAgent(agentId, agentInfo, projectDir);
113
+ restoredAgents.push(agent);
114
+ } catch (error) {
115
+ this.logger.warn(`Failed to restore agent: ${agentId}`, error.message);
116
+ }
117
+ }
118
+
119
+ // Restore async operations
120
+ const asyncOperations = await this.restoreAsyncOperations(projectDir);
121
+
122
+ // Restore paused agents
123
+ const pausedAgents = await this.restorePausedAgents(projectDir);
124
+
125
+ // Restore context references
126
+ const contextReferences = await this.restoreContextReferences(projectDir);
127
+
128
+ const resumedState = {
129
+ projectState,
130
+ agents: restoredAgents,
131
+ asyncOperations,
132
+ pausedAgents,
133
+ contextReferences,
134
+ resumedSuccessfully: true,
135
+ resumedAt: new Date().toISOString()
136
+ };
137
+
138
+ // Update last session
139
+ await this.saveLastSession(projectDir, {
140
+ resumedAt: new Date().toISOString(),
141
+ agentCount: restoredAgents.length,
142
+ operationCount: asyncOperations.length
143
+ });
144
+
145
+ this.logger.info(`Project resumed successfully`, {
146
+ projectDir,
147
+ agentCount: restoredAgents.length,
148
+ operationCount: asyncOperations.length
149
+ });
150
+
151
+ return resumedState;
152
+
153
+ } catch (error) {
154
+ this.logger.error(`Project resume failed: ${error.message}`, {
155
+ projectDir,
156
+ error: error.stack
157
+ });
158
+
159
+ return {
160
+ projectState: null,
161
+ agents: [],
162
+ asyncOperations: [],
163
+ pausedAgents: [],
164
+ contextReferences: [],
165
+ resumedSuccessfully: false,
166
+ error: error.message
167
+ };
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Persist agent state to storage
173
+ * @param {Object} agent - Agent object to persist
174
+ * @param {string} projectDir - Project directory path
175
+ * @returns {Promise<void>}
176
+ */
177
+ async persistAgentState(agent, projectDir = process.cwd()) {
178
+ const stateDir = this.getStateDir(projectDir);
179
+ const agentStateFile = path.join(stateDir, 'agents', `agent-${agent.id}-state.json`);
180
+ const agentConversationsFile = path.join(stateDir, 'agents', `agent-${agent.id}-conversations.json`);
181
+
182
+ try {
183
+ // Separate conversations from main agent state
184
+ const { conversations, ...agentState } = agent;
185
+
186
+ // Save agent state
187
+ await this.saveJSON(agentStateFile, {
188
+ version: this.stateVersion,
189
+ agentId: agent.id,
190
+ state: agentState,
191
+ lastPersisted: new Date().toISOString()
192
+ });
193
+
194
+ // Save conversations separately
195
+ await this.saveJSON(agentConversationsFile, {
196
+ version: this.stateVersion,
197
+ agentId: agent.id,
198
+ conversations,
199
+ lastPersisted: new Date().toISOString()
200
+ });
201
+
202
+ // Update agent index
203
+ await this.updateAgentIndex(agent, projectDir);
204
+
205
+ this.logger.debug(`Agent state persisted: ${agent.id}`);
206
+
207
+ } catch (error) {
208
+ this.logger.error(`Failed to persist agent state: ${error.message}`, {
209
+ agentId: agent.id,
210
+ error: error.stack
211
+ });
212
+ throw error;
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Get project state
218
+ * @param {string} projectDir - Project directory path
219
+ * @returns {Promise<Object>} Project state object
220
+ */
221
+ async getProjectState(projectDir) {
222
+ return await this.loadProjectState(projectDir);
223
+ }
224
+
225
+ /**
226
+ * Load project state from storage
227
+ * @param {string} projectDir - Project directory path
228
+ * @returns {Promise<Object>} Project state object
229
+ */
230
+ async loadProjectState(projectDir) {
231
+ const stateFile = path.join(this.stateDirectory, this.stateFiles.projectState);
232
+
233
+ try {
234
+ const data = await this.loadJSON(stateFile);
235
+ return data;
236
+ } catch (error) {
237
+ // Return default project state if file doesn't exist
238
+ const defaultState = {
239
+ version: this.stateVersion,
240
+ projectDir,
241
+ createdAt: new Date().toISOString(),
242
+ lastModified: new Date().toISOString(),
243
+ activeAgents: [],
244
+ lastActiveSession: null,
245
+ configuration: {
246
+ defaultModel: this.config.system?.defaultModel || 'anthropic-sonnet',
247
+ allowedTools: ['terminal', 'filesystem', 'browser'],
248
+ budgetLimit: 100.00
249
+ }
250
+ };
251
+
252
+ await this.saveProjectState(projectDir, defaultState);
253
+ return defaultState;
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Save project state to storage
259
+ * @param {string} projectDir - Project directory path
260
+ * @param {Object} projectState - Project state object
261
+ * @returns {Promise<void>}
262
+ */
263
+ async saveProjectState(projectDir, projectState) {
264
+ const stateFile = path.join(this.stateDirectory, this.stateFiles.projectState);
265
+
266
+ const stateData = {
267
+ ...projectState,
268
+ lastModified: new Date().toISOString()
269
+ };
270
+
271
+ await this.saveJSON(stateFile, stateData);
272
+ }
273
+
274
+ /**
275
+ * Load agent index
276
+ * @param {string} projectDir - Project directory path
277
+ * @returns {Promise<Object>} Agent index object
278
+ */
279
+ async loadAgentIndex(projectDir) {
280
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.agentIndex);
281
+
282
+ try {
283
+ return await this.loadJSON(indexFile);
284
+ } catch (error) {
285
+ return {}; // Return empty index if file doesn't exist
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Update agent index
291
+ * @param {Object} agent - Agent object
292
+ * @param {string} projectDir - Project directory path
293
+ * @returns {Promise<void>}
294
+ */
295
+ async updateAgentIndex(agent, projectDir) {
296
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.agentIndex);
297
+
298
+ let agentIndex;
299
+ try {
300
+ agentIndex = await this.loadJSON(indexFile);
301
+ } catch {
302
+ agentIndex = {};
303
+ }
304
+
305
+ agentIndex[agent.id] = {
306
+ name: agent.name,
307
+ type: agent.type,
308
+ stateFile: `agents/agent-${agent.id}-state.json`,
309
+ conversationsFile: `agents/agent-${agent.id}-conversations.json`,
310
+ lastActivity: agent.lastActivity,
311
+ model: agent.currentModel,
312
+ status: agent.status,
313
+ capabilities: agent.capabilities || []
314
+ };
315
+
316
+ await this.saveJSON(indexFile, agentIndex);
317
+ }
318
+
319
+ // ==================== TEAM INDEX METHODS ====================
320
+
321
+ /**
322
+ * Load team index
323
+ * @param {string} projectDir - Project directory path (ignored, uses user data dir)
324
+ * @returns {Promise<Object>} Team index object
325
+ */
326
+ async loadTeamIndex(projectDir) {
327
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.teamIndex);
328
+
329
+ try {
330
+ return await this.loadJSON(indexFile);
331
+ } catch (error) {
332
+ return {}; // Return empty index if file doesn't exist
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Save team index
338
+ * @param {Object} teamIndex - Team index object to save
339
+ * @returns {Promise<void>}
340
+ */
341
+ async saveTeamIndex(teamIndex) {
342
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.teamIndex);
343
+ await this.saveJSON(indexFile, teamIndex);
344
+ }
345
+
346
+ /**
347
+ * Get all teams
348
+ * @param {string} projectDir - Project directory path (ignored)
349
+ * @returns {Promise<Array>} Array of team objects
350
+ */
351
+ async getAllTeams(projectDir) {
352
+ const teamIndex = await this.loadTeamIndex(projectDir);
353
+ return Object.entries(teamIndex).map(([id, team]) => ({
354
+ id,
355
+ ...team
356
+ }));
357
+ }
358
+
359
+ /**
360
+ * Get a single team by ID
361
+ * @param {string} teamId - Team identifier
362
+ * @param {string} projectDir - Project directory path (ignored)
363
+ * @returns {Promise<Object|null>} Team object or null if not found
364
+ */
365
+ async getTeam(teamId, projectDir) {
366
+ const teamIndex = await this.loadTeamIndex(projectDir);
367
+ if (teamIndex[teamId]) {
368
+ return { id: teamId, ...teamIndex[teamId] };
369
+ }
370
+ return null;
371
+ }
372
+
373
+ /**
374
+ * Create a new team
375
+ * @param {Object} teamData - Team data { name, description, color }
376
+ * @param {string} projectDir - Project directory path (ignored)
377
+ * @returns {Promise<Object>} Created team object
378
+ */
379
+ async createTeam(teamData, projectDir) {
380
+ const teamIndex = await this.loadTeamIndex(projectDir);
381
+
382
+ // Generate team ID
383
+ const safeName = (teamData.name || 'team').toLowerCase().replace(/[^a-z0-9]/g, '-').slice(0, 20);
384
+ const teamId = `team-${safeName}-${Date.now()}`;
385
+
386
+ const team = {
387
+ name: teamData.name,
388
+ description: teamData.description || '',
389
+ memberAgentIds: [],
390
+ color: teamData.color || '#3B82F6', // Default blue
391
+ createdAt: new Date().toISOString(),
392
+ updatedAt: new Date().toISOString()
393
+ };
394
+
395
+ teamIndex[teamId] = team;
396
+ await this.saveTeamIndex(teamIndex);
397
+
398
+ this.logger.info(`Team created: ${teamId}`, { name: team.name });
399
+
400
+ return { id: teamId, ...team };
401
+ }
402
+
403
+ /**
404
+ * Update an existing team
405
+ * @param {string} teamId - Team identifier
406
+ * @param {Object} updates - Fields to update
407
+ * @param {string} projectDir - Project directory path (ignored)
408
+ * @returns {Promise<Object>} Updated team object
409
+ */
410
+ async updateTeam(teamId, updates, projectDir) {
411
+ const teamIndex = await this.loadTeamIndex(projectDir);
412
+
413
+ if (!teamIndex[teamId]) {
414
+ throw new Error(`Team ${teamId} not found`);
415
+ }
416
+
417
+ // Only allow updating specific fields
418
+ const allowedFields = ['name', 'description', 'color', 'memberAgentIds'];
419
+ for (const field of allowedFields) {
420
+ if (updates[field] !== undefined) {
421
+ teamIndex[teamId][field] = updates[field];
422
+ }
423
+ }
424
+ teamIndex[teamId].updatedAt = new Date().toISOString();
425
+
426
+ await this.saveTeamIndex(teamIndex);
427
+
428
+ this.logger.info(`Team updated: ${teamId}`, { updates: Object.keys(updates) });
429
+
430
+ return { id: teamId, ...teamIndex[teamId] };
431
+ }
432
+
433
+ /**
434
+ * Delete a team
435
+ * @param {string} teamId - Team identifier
436
+ * @param {string} projectDir - Project directory path (ignored)
437
+ * @returns {Promise<boolean>} True if deleted
438
+ */
439
+ async deleteTeam(teamId, projectDir) {
440
+ const teamIndex = await this.loadTeamIndex(projectDir);
441
+
442
+ if (!teamIndex[teamId]) {
443
+ throw new Error(`Team ${teamId} not found`);
444
+ }
445
+
446
+ const teamName = teamIndex[teamId].name;
447
+ delete teamIndex[teamId];
448
+ await this.saveTeamIndex(teamIndex);
449
+
450
+ this.logger.info(`Team deleted: ${teamId}`, { name: teamName });
451
+
452
+ return true;
453
+ }
454
+
455
+ /**
456
+ * Add an agent to a team
457
+ * @param {string} teamId - Team identifier
458
+ * @param {string} agentId - Agent identifier to add
459
+ * @param {string} projectDir - Project directory path (ignored)
460
+ * @returns {Promise<Object>} Updated team object
461
+ */
462
+ async addAgentToTeam(teamId, agentId, projectDir) {
463
+ const teamIndex = await this.loadTeamIndex(projectDir);
464
+
465
+ if (!teamIndex[teamId]) {
466
+ throw new Error(`Team ${teamId} not found`);
467
+ }
468
+
469
+ // Check if agent already in team
470
+ if (!teamIndex[teamId].memberAgentIds.includes(agentId)) {
471
+ teamIndex[teamId].memberAgentIds.push(agentId);
472
+ teamIndex[teamId].updatedAt = new Date().toISOString();
473
+ await this.saveTeamIndex(teamIndex);
474
+
475
+ this.logger.info(`Agent added to team`, { teamId, agentId });
476
+ }
477
+
478
+ return { id: teamId, ...teamIndex[teamId] };
479
+ }
480
+
481
+ /**
482
+ * Remove an agent from a team
483
+ * @param {string} teamId - Team identifier
484
+ * @param {string} agentId - Agent identifier to remove
485
+ * @param {string} projectDir - Project directory path (ignored)
486
+ * @returns {Promise<Object>} Updated team object
487
+ */
488
+ async removeAgentFromTeam(teamId, agentId, projectDir) {
489
+ const teamIndex = await this.loadTeamIndex(projectDir);
490
+
491
+ if (!teamIndex[teamId]) {
492
+ throw new Error(`Team ${teamId} not found`);
493
+ }
494
+
495
+ const index = teamIndex[teamId].memberAgentIds.indexOf(agentId);
496
+ if (index > -1) {
497
+ teamIndex[teamId].memberAgentIds.splice(index, 1);
498
+ teamIndex[teamId].updatedAt = new Date().toISOString();
499
+ await this.saveTeamIndex(teamIndex);
500
+
501
+ this.logger.info(`Agent removed from team`, { teamId, agentId });
502
+ }
503
+
504
+ return { id: teamId, ...teamIndex[teamId] };
505
+ }
506
+
507
+ /**
508
+ * Get all teams that contain a specific agent
509
+ * @param {string} agentId - Agent identifier
510
+ * @param {string} projectDir - Project directory path (ignored)
511
+ * @returns {Promise<Array>} Array of team objects containing the agent
512
+ */
513
+ async getAgentTeams(agentId, projectDir) {
514
+ const teams = await this.getAllTeams(projectDir);
515
+ return teams.filter(team => team.memberAgentIds.includes(agentId));
516
+ }
517
+
518
+ // ==================== END TEAM INDEX METHODS ====================
519
+
520
+ // ==================== FLOW INDEX METHODS ====================
521
+
522
+ /**
523
+ * Load flow index
524
+ * @param {string} projectDir - Project directory path (ignored, uses user data dir)
525
+ * @returns {Promise<Object>} Flow index object
526
+ */
527
+ async loadFlowIndex(projectDir) {
528
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.flowIndex);
529
+
530
+ try {
531
+ return await this.loadJSON(indexFile);
532
+ } catch (error) {
533
+ return {}; // Return empty index if file doesn't exist
534
+ }
535
+ }
536
+
537
+ /**
538
+ * Save flow index
539
+ * @param {Object} flowIndex - Flow index object to save
540
+ * @returns {Promise<void>}
541
+ */
542
+ async saveFlowIndex(flowIndex) {
543
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.flowIndex);
544
+ await this.saveJSON(indexFile, flowIndex);
545
+ }
546
+
547
+ /**
548
+ * Get all flows
549
+ * @param {string} projectDir - Project directory path (ignored)
550
+ * @returns {Promise<Array>} Array of flow objects
551
+ */
552
+ async getAllFlows(projectDir) {
553
+ const flowIndex = await this.loadFlowIndex(projectDir);
554
+ return Object.entries(flowIndex).map(([id, flow]) => ({
555
+ id,
556
+ ...flow
557
+ }));
558
+ }
559
+
560
+ /**
561
+ * Get a single flow by ID
562
+ * @param {string} flowId - Flow identifier
563
+ * @param {string} projectDir - Project directory path (ignored)
564
+ * @returns {Promise<Object|null>} Flow object or null if not found
565
+ */
566
+ async getFlow(flowId, projectDir) {
567
+ const flowIndex = await this.loadFlowIndex(projectDir);
568
+ if (flowIndex[flowId]) {
569
+ return { id: flowId, ...flowIndex[flowId] };
570
+ }
571
+ return null;
572
+ }
573
+
574
+ /**
575
+ * Create a new flow
576
+ * @param {Object} flowData - Flow data { name, description, nodes, edges, variables }
577
+ * @param {string} projectDir - Project directory path (ignored)
578
+ * @returns {Promise<Object>} Created flow object
579
+ */
580
+ async createFlow(flowData, projectDir) {
581
+ const flowIndex = await this.loadFlowIndex(projectDir);
582
+
583
+ // Generate flow ID
584
+ const safeName = (flowData.name || 'flow').toLowerCase().replace(/[^a-z0-9]/g, '-').slice(0, 20);
585
+ const flowId = `flow-${safeName}-${Date.now()}`;
586
+
587
+ const flow = {
588
+ name: flowData.name,
589
+ description: flowData.description || '',
590
+ nodes: flowData.nodes || [],
591
+ edges: flowData.edges || [],
592
+ variables: flowData.variables || {},
593
+ createdAt: new Date().toISOString(),
594
+ updatedAt: new Date().toISOString()
595
+ };
596
+
597
+ flowIndex[flowId] = flow;
598
+ await this.saveFlowIndex(flowIndex);
599
+
600
+ this.logger.info(`Flow created: ${flowId}`, { name: flow.name });
601
+
602
+ return { id: flowId, ...flow };
603
+ }
604
+
605
+ /**
606
+ * Update an existing flow
607
+ * @param {string} flowId - Flow identifier
608
+ * @param {Object} updates - Fields to update
609
+ * @param {string} projectDir - Project directory path (ignored)
610
+ * @returns {Promise<Object>} Updated flow object
611
+ */
612
+ async updateFlow(flowId, updates, projectDir) {
613
+ const flowIndex = await this.loadFlowIndex(projectDir);
614
+
615
+ if (!flowIndex[flowId]) {
616
+ throw new Error(`Flow ${flowId} not found`);
617
+ }
618
+
619
+ // Only allow updating specific fields
620
+ const allowedFields = ['name', 'description', 'nodes', 'edges', 'variables'];
621
+ for (const field of allowedFields) {
622
+ if (updates[field] !== undefined) {
623
+ flowIndex[flowId][field] = updates[field];
624
+ }
625
+ }
626
+ flowIndex[flowId].updatedAt = new Date().toISOString();
627
+
628
+ await this.saveFlowIndex(flowIndex);
629
+
630
+ this.logger.info(`Flow updated: ${flowId}`, { updates: Object.keys(updates) });
631
+
632
+ return { id: flowId, ...flowIndex[flowId] };
633
+ }
634
+
635
+ /**
636
+ * Delete a flow
637
+ * @param {string} flowId - Flow identifier
638
+ * @param {string} projectDir - Project directory path (ignored)
639
+ * @returns {Promise<boolean>} True if deleted
640
+ */
641
+ async deleteFlow(flowId, projectDir) {
642
+ const flowIndex = await this.loadFlowIndex(projectDir);
643
+
644
+ if (!flowIndex[flowId]) {
645
+ throw new Error(`Flow ${flowId} not found`);
646
+ }
647
+
648
+ const flowName = flowIndex[flowId].name;
649
+ delete flowIndex[flowId];
650
+ await this.saveFlowIndex(flowIndex);
651
+
652
+ this.logger.info(`Flow deleted: ${flowId}`, { name: flowName });
653
+
654
+ return true;
655
+ }
656
+
657
+ // ==================== FLOW RUN METHODS ====================
658
+
659
+ /**
660
+ * Load flow run index
661
+ * @param {string} projectDir - Project directory path (ignored)
662
+ * @returns {Promise<Object>} Flow run index object
663
+ */
664
+ async loadFlowRunIndex(projectDir) {
665
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.flowRunIndex);
666
+
667
+ try {
668
+ return await this.loadJSON(indexFile);
669
+ } catch (error) {
670
+ return {}; // Return empty index if file doesn't exist
671
+ }
672
+ }
673
+
674
+ /**
675
+ * Save flow run index
676
+ * @param {Object} runIndex - Flow run index object to save
677
+ * @returns {Promise<void>}
678
+ */
679
+ async saveFlowRunIndex(runIndex) {
680
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.flowRunIndex);
681
+ await this.saveJSON(indexFile, runIndex);
682
+ }
683
+
684
+ /**
685
+ * Create a new flow run
686
+ * @param {string} flowId - Flow identifier
687
+ * @param {Object} initialInput - Initial input for the flow
688
+ * @param {string} projectDir - Project directory path (ignored)
689
+ * @returns {Promise<Object>} Created flow run object
690
+ */
691
+ async createFlowRun(flowId, initialInput, projectDir) {
692
+ const runIndex = await this.loadFlowRunIndex(projectDir);
693
+
694
+ const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
695
+
696
+ const run = {
697
+ flowId,
698
+ status: 'pending', // pending, running, completed, failed, stopped
699
+ initialInput,
700
+ nodeStates: {},
701
+ startedAt: new Date().toISOString(),
702
+ completedAt: null,
703
+ error: null
704
+ };
705
+
706
+ runIndex[runId] = run;
707
+ await this.saveFlowRunIndex(runIndex);
708
+
709
+ this.logger.info(`Flow run created: ${runId}`, { flowId });
710
+
711
+ return { id: runId, ...run };
712
+ }
713
+
714
+ /**
715
+ * Update a flow run
716
+ * @param {string} runId - Run identifier
717
+ * @param {Object} updates - Fields to update
718
+ * @param {string} projectDir - Project directory path (ignored)
719
+ * @returns {Promise<Object>} Updated flow run object
720
+ */
721
+ async updateFlowRun(runId, updates, projectDir) {
722
+ const runIndex = await this.loadFlowRunIndex(projectDir);
723
+
724
+ if (!runIndex[runId]) {
725
+ throw new Error(`Flow run ${runId} not found`);
726
+ }
727
+
728
+ // Only allow updating specific fields
729
+ const allowedFields = ['status', 'nodeStates', 'completedAt', 'error', 'output'];
730
+ for (const field of allowedFields) {
731
+ if (updates[field] !== undefined) {
732
+ runIndex[runId][field] = updates[field];
733
+ }
734
+ }
735
+
736
+ await this.saveFlowRunIndex(runIndex);
737
+
738
+ this.logger.info(`Flow run updated: ${runId}`, { status: updates.status });
739
+
740
+ return { id: runId, ...runIndex[runId] };
741
+ }
742
+
743
+ /**
744
+ * Get a flow run by ID
745
+ * @param {string} runId - Run identifier
746
+ * @param {string} projectDir - Project directory path (ignored)
747
+ * @returns {Promise<Object|null>} Flow run object or null if not found
748
+ */
749
+ async getFlowRun(runId, projectDir) {
750
+ const runIndex = await this.loadFlowRunIndex(projectDir);
751
+ if (runIndex[runId]) {
752
+ return { id: runId, ...runIndex[runId] };
753
+ }
754
+ return null;
755
+ }
756
+
757
+ /**
758
+ * Get all runs for a specific flow
759
+ * @param {string} flowId - Flow identifier
760
+ * @param {string} projectDir - Project directory path (ignored)
761
+ * @returns {Promise<Array>} Array of flow run objects
762
+ */
763
+ async getFlowRuns(flowId, projectDir) {
764
+ const runIndex = await this.loadFlowRunIndex(projectDir);
765
+ return Object.entries(runIndex)
766
+ .filter(([, run]) => run.flowId === flowId)
767
+ .map(([id, run]) => ({ id, ...run }))
768
+ .sort((a, b) => new Date(b.startedAt) - new Date(a.startedAt));
769
+ }
770
+
771
+ // ==================== END FLOW INDEX METHODS ====================
772
+
773
+ /**
774
+ * Restore agent from saved state
775
+ * @param {string} agentId - Agent identifier
776
+ * @param {Object} agentInfo - Agent info from index
777
+ * @param {string} projectDir - Project directory path
778
+ * @returns {Promise<Object>} Restored agent object
779
+ */
780
+ async restoreAgent(agentId, agentInfo, projectDir) {
781
+ const stateDir = this.getStateDir(projectDir);
782
+ const stateFile = path.join(stateDir, agentInfo.stateFile);
783
+ const conversationsFile = path.join(stateDir, agentInfo.conversationsFile);
784
+
785
+ try {
786
+ // Load agent state
787
+ const stateData = await this.loadJSON(stateFile);
788
+ const conversationsData = await this.loadJSON(conversationsFile);
789
+
790
+ // Validate model conversations integrity
791
+ await this.validateModelConversations(conversationsData.conversations);
792
+
793
+ // Check if agent is paused
794
+ const pauseStatus = await this.checkAgentPauseStatus(agentId, projectDir);
795
+
796
+ const restoredAgent = {
797
+ ...stateData.state,
798
+ conversations: conversationsData.conversations,
799
+ isPaused: pauseStatus.isPaused,
800
+ pausedUntil: pauseStatus.pausedUntil,
801
+ isRestored: true,
802
+ restoredAt: new Date().toISOString()
803
+ };
804
+
805
+ // CRITICAL: Restore interAgentTracking as a Map (it comes as plain object from JSON)
806
+ if (!restoredAgent.interAgentTracking || typeof restoredAgent.interAgentTracking !== 'object') {
807
+ restoredAgent.interAgentTracking = new Map();
808
+ } else if (!(restoredAgent.interAgentTracking instanceof Map)) {
809
+ restoredAgent.interAgentTracking = new Map(Object.entries(restoredAgent.interAgentTracking));
810
+ }
811
+
812
+ this.logger.info(`Agent restored: ${agentId}`, {
813
+ name: restoredAgent.name,
814
+ status: restoredAgent.status,
815
+ messageCount: restoredAgent.conversations?.full?.messages?.length || 0
816
+ });
817
+
818
+ return restoredAgent;
819
+
820
+ } catch (error) {
821
+ this.logger.error(`Agent restoration failed: ${agentId}`, error.message);
822
+ throw error;
823
+ }
824
+ }
825
+
826
+ /**
827
+ * Restore async operations
828
+ * @param {string} projectDir - Project directory path
829
+ * @returns {Promise<Array>} Array of active async operations
830
+ */
831
+ async restoreAsyncOperations(projectDir) {
832
+ const operationsFile = path.join(this.stateDirectory, this.stateFiles.asyncOperations);
833
+
834
+ try {
835
+ const data = await this.loadJSON(operationsFile);
836
+ return data.operations || [];
837
+ } catch {
838
+ return [];
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Restore paused agents
844
+ * @param {string} projectDir - Project directory path
845
+ * @returns {Promise<Object>} Paused agents data
846
+ */
847
+ async restorePausedAgents(projectDir) {
848
+ const pausedFile = path.join(this.stateDirectory, this.stateFiles.pausedAgents);
849
+
850
+ try {
851
+ const data = await this.loadJSON(pausedFile);
852
+ const now = Date.now();
853
+
854
+ // Check which agents should be resumed
855
+ const toResume = [];
856
+ for (const [agentId, pauseInfo] of Object.entries(data.pausedAgents || {})) {
857
+ const pausedUntil = new Date(pauseInfo.pausedUntil).getTime();
858
+
859
+ if (now >= pausedUntil) {
860
+ toResume.push(agentId);
861
+ }
862
+ }
863
+
864
+ // Move expired pauses to history
865
+ for (const agentId of toResume) {
866
+ const pauseInfo = data.pausedAgents[agentId];
867
+ delete data.pausedAgents[agentId];
868
+
869
+ data.pauseHistory = data.pauseHistory || [];
870
+ data.pauseHistory.push({
871
+ agentId,
872
+ pausedAt: pauseInfo.pausedAt,
873
+ resumedAt: new Date().toISOString(),
874
+ reason: pauseInfo.reason,
875
+ actualDuration: Math.round((now - new Date(pauseInfo.pausedAt).getTime()) / 1000)
876
+ });
877
+ }
878
+
879
+ // Save updated data
880
+ await this.saveJSON(pausedFile, data);
881
+
882
+ return data;
883
+
884
+ } catch {
885
+ return {
886
+ pausedAgents: {},
887
+ pauseHistory: []
888
+ };
889
+ }
890
+ }
891
+
892
+ /**
893
+ * Restore context references
894
+ * @param {string} projectDir - Project directory path
895
+ * @returns {Promise<Object>} Context references data
896
+ */
897
+ async restoreContextReferences(projectDir) {
898
+ const contextFile = path.join(this.stateDirectory, this.stateFiles.contextReferences);
899
+
900
+ try {
901
+ const data = await this.loadJSON(contextFile);
902
+
903
+ // Validate context references (implementation would validate file existence, etc.)
904
+ const validatedReferences = [];
905
+ for (const reference of data.references || []) {
906
+ // Add validation logic here
907
+ reference.isValid = true; // Placeholder
908
+ reference.lastValidated = new Date().toISOString();
909
+ validatedReferences.push(reference);
910
+ }
911
+
912
+ data.references = validatedReferences;
913
+ await this.saveJSON(contextFile, data);
914
+
915
+ return data;
916
+
917
+ } catch {
918
+ return {
919
+ references: [],
920
+ lastCleanup: new Date().toISOString()
921
+ };
922
+ }
923
+ }
924
+
925
+ /**
926
+ * Save last session data
927
+ * @param {string} projectDir - Project directory path
928
+ * @param {Object} sessionData - Session data to save
929
+ * @returns {Promise<void>}
930
+ */
931
+ async saveLastSession(projectDir, sessionData) {
932
+ const sessionFile = path.join(this.stateDirectory, this.stateFiles.lastSession);
933
+
934
+ const data = {
935
+ ...sessionData,
936
+ savedAt: new Date().toISOString(),
937
+ projectDir
938
+ };
939
+
940
+ await this.saveJSON(sessionFile, data);
941
+ }
942
+
943
+ /**
944
+ * Load last session data
945
+ * @param {string} projectDir - Project directory path
946
+ * @returns {Promise<Object>} Last session data
947
+ */
948
+ async loadLastSession(projectDir) {
949
+ const sessionFile = path.join(this.stateDirectory, this.stateFiles.lastSession);
950
+
951
+ try {
952
+ return await this.loadJSON(sessionFile);
953
+ } catch {
954
+ return null;
955
+ }
956
+ }
957
+
958
+ /**
959
+ * Save paused agent data
960
+ * @param {string} projectDir - Project directory path
961
+ * @param {string} agentId - Agent identifier
962
+ * @param {Object} pauseData - Pause information
963
+ * @returns {Promise<void>}
964
+ */
965
+ async savePausedAgent(projectDir, agentId, pauseData) {
966
+ const pausedFile = path.join(this.stateDirectory, this.stateFiles.pausedAgents);
967
+
968
+ let data;
969
+ try {
970
+ data = await this.loadJSON(pausedFile);
971
+ } catch {
972
+ data = { pausedAgents: {}, pauseHistory: [] };
973
+ }
974
+
975
+ data.pausedAgents[agentId] = pauseData;
976
+ await this.saveJSON(pausedFile, data);
977
+ }
978
+
979
+ /**
980
+ * Remove paused agent data
981
+ * @param {string} projectDir - Project directory path
982
+ * @param {string} agentId - Agent identifier
983
+ * @returns {Promise<void>}
984
+ */
985
+ async removePausedAgent(projectDir, agentId) {
986
+ const pausedFile = path.join(this.stateDirectory, this.stateFiles.pausedAgents);
987
+
988
+ try {
989
+ const data = await this.loadJSON(pausedFile);
990
+ delete data.pausedAgents[agentId];
991
+ await this.saveJSON(pausedFile, data);
992
+ } catch {
993
+ // File doesn't exist, nothing to remove
994
+ }
995
+ }
996
+
997
+ /**
998
+ * Check agent pause status
999
+ * @param {string} agentId - Agent identifier
1000
+ * @param {string} projectDir - Project directory path
1001
+ * @returns {Promise<Object>} Pause status
1002
+ */
1003
+ async checkAgentPauseStatus(agentId, projectDir) {
1004
+ const pausedFile = path.join(this.stateDirectory, this.stateFiles.pausedAgents);
1005
+
1006
+ try {
1007
+ const data = await this.loadJSON(pausedFile);
1008
+ const pauseInfo = data.pausedAgents[agentId];
1009
+
1010
+ if (!pauseInfo) {
1011
+ return { isPaused: false, pausedUntil: null };
1012
+ }
1013
+
1014
+ const now = Date.now();
1015
+ const pausedUntil = new Date(pauseInfo.pausedUntil).getTime();
1016
+
1017
+ return {
1018
+ isPaused: now < pausedUntil,
1019
+ pausedUntil: pauseInfo.pausedUntil,
1020
+ reason: pauseInfo.reason
1021
+ };
1022
+
1023
+ } catch {
1024
+ return { isPaused: false, pausedUntil: null };
1025
+ }
1026
+ }
1027
+
1028
+ /**
1029
+ * Validate model conversations integrity
1030
+ * @param {Object} conversations - Conversations object
1031
+ * @returns {Promise<void>}
1032
+ */
1033
+ async validateModelConversations(conversations) {
1034
+ if (!conversations || !conversations.full) {
1035
+ throw new Error('Invalid conversations structure - missing full conversation');
1036
+ }
1037
+
1038
+ const fullMessages = conversations.full.messages || [];
1039
+ const fullLastUpdated = new Date(conversations.full.lastUpdated);
1040
+
1041
+ // Validate each model conversation against full conversation
1042
+ for (const [modelName, modelConv] of Object.entries(conversations)) {
1043
+ if (modelName === 'full') continue;
1044
+
1045
+ if (!modelConv.messages) {
1046
+ this.logger.warn(`Model conversation ${modelName} missing messages array`);
1047
+ continue;
1048
+ }
1049
+
1050
+ const modelLastUpdated = new Date(modelConv.lastUpdated);
1051
+
1052
+ if (fullLastUpdated > modelLastUpdated) {
1053
+ this.logger.warn(`Model conversation ${modelName} is outdated, will sync on next use`);
1054
+ modelConv.needsSync = true;
1055
+ }
1056
+ }
1057
+ }
1058
+
1059
+ /**
1060
+ * Save JSON data to file
1061
+ * @private
1062
+ */
1063
+ async saveJSON(filePath, data) {
1064
+ const dir = path.dirname(filePath);
1065
+ await fs.mkdir(dir, { recursive: true });
1066
+
1067
+ const jsonData = JSON.stringify(data, null, 2);
1068
+ await fs.writeFile(filePath, jsonData, 'utf8');
1069
+ }
1070
+
1071
+ /**
1072
+ * Load JSON data from file
1073
+ * @private
1074
+ */
1075
+ async loadJSON(filePath) {
1076
+ const data = await fs.readFile(filePath, 'utf8');
1077
+ return JSON.parse(data);
1078
+ }
1079
+
1080
+ /**
1081
+ * Delete agent state from storage
1082
+ * @param {string} agentId - Agent identifier
1083
+ * @param {string} projectDir - Project directory path
1084
+ * @returns {Promise<void>}
1085
+ */
1086
+ async deleteAgentState(agentId, projectDir = process.cwd()) {
1087
+ const stateDir = this.getStateDir(projectDir);
1088
+ const agentStateFile = path.join(stateDir, 'agents', `agent-${agentId}-state.json`);
1089
+ const agentConversationsFile = path.join(stateDir, 'agents', `agent-${agentId}-conversations.json`);
1090
+
1091
+ try {
1092
+ // Delete agent state file
1093
+ try {
1094
+ await fs.unlink(agentStateFile);
1095
+ this.logger.debug(`Deleted agent state file: ${agentId}`);
1096
+ } catch (error) {
1097
+ if (error.code !== 'ENOENT') {
1098
+ this.logger.warn(`Failed to delete agent state file: ${error.message}`, { agentId });
1099
+ }
1100
+ }
1101
+
1102
+ // Delete agent conversations file
1103
+ try {
1104
+ await fs.unlink(agentConversationsFile);
1105
+ this.logger.debug(`Deleted agent conversations file: ${agentId}`);
1106
+ } catch (error) {
1107
+ if (error.code !== 'ENOENT') {
1108
+ this.logger.warn(`Failed to delete agent conversations file: ${error.message}`, { agentId });
1109
+ }
1110
+ }
1111
+
1112
+ // Remove from agent index
1113
+ await this.removeFromAgentIndex(agentId, projectDir);
1114
+
1115
+ this.logger.info(`Agent state deleted: ${agentId}`);
1116
+
1117
+ } catch (error) {
1118
+ this.logger.error(`Failed to delete agent state: ${error.message}`, {
1119
+ agentId,
1120
+ error: error.stack
1121
+ });
1122
+ throw error;
1123
+ }
1124
+ }
1125
+
1126
+ /**
1127
+ * Remove agent from agent index
1128
+ * @param {string} agentId - Agent identifier
1129
+ * @param {string} projectDir - Project directory path
1130
+ * @returns {Promise<void>}
1131
+ */
1132
+ async removeFromAgentIndex(agentId, projectDir) {
1133
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.agentIndex);
1134
+
1135
+ try {
1136
+ const agentIndex = await this.loadJSON(indexFile);
1137
+ delete agentIndex[agentId];
1138
+ await this.saveJSON(indexFile, agentIndex);
1139
+ this.logger.debug(`Removed agent from index: ${agentId}`);
1140
+ } catch (error) {
1141
+ // If index doesn't exist or can't be updated, log but don't throw
1142
+ this.logger.warn(`Failed to remove agent from index: ${error.message}`, { agentId });
1143
+ }
1144
+ }
1145
+
1146
+ /**
1147
+ * Check if state directory exists
1148
+ * @param {string} projectDir - Project directory path
1149
+ * @returns {Promise<boolean>} True if state directory exists
1150
+ */
1151
+ async stateDirectoryExists(projectDir) {
1152
+ const stateDir = this.getStateDir(projectDir);
1153
+
1154
+ try {
1155
+ const stats = await fs.stat(stateDir);
1156
+ return stats.isDirectory();
1157
+ } catch {
1158
+ return false;
1159
+ }
1160
+ }
1161
+
1162
+ /**
1163
+ * Clean up old state files
1164
+ * @param {string} projectDir - Project directory path
1165
+ * @param {number} maxAge - Maximum age in days
1166
+ * @returns {Promise<void>}
1167
+ */
1168
+ async cleanupOldState(projectDir, maxAge = 30) {
1169
+ const stateDir = this.getStateDir(projectDir);
1170
+ const cutoffDate = Date.now() - (maxAge * 24 * 60 * 60 * 1000);
1171
+
1172
+ try {
1173
+ const agentsDir = path.join(stateDir, 'agents');
1174
+ const files = await fs.readdir(agentsDir);
1175
+
1176
+ for (const file of files) {
1177
+ const filePath = path.join(agentsDir, file);
1178
+ const stats = await fs.stat(filePath);
1179
+
1180
+ if (stats.mtime.getTime() < cutoffDate) {
1181
+ await fs.unlink(filePath);
1182
+ this.logger.info(`Cleaned up old state file: ${file}`);
1183
+ }
1184
+ }
1185
+
1186
+ } catch (error) {
1187
+ this.logger.warn(`State cleanup failed: ${error.message}`);
1188
+ }
1189
+ }
1190
+
1191
+ /**
1192
+ * Get all available agents (active + archived) from filesystem
1193
+ * Scans both the index AND the agents directory to find all agents,
1194
+ * including those that may be missing from the index.
1195
+ * @param {string} projectDir - Project directory path
1196
+ * @param {Object} agentPool - Agent pool instance to check active agents
1197
+ * @returns {Promise<Array>} List of all agents with metadata
1198
+ */
1199
+ async getAllAvailableAgents(projectDir, agentPool) {
1200
+ try {
1201
+ const agentIndex = await this.loadAgentIndex(projectDir);
1202
+ const activeAgentIds = agentPool ? (await agentPool.getAllAgents()).map(a => a.id) : [];
1203
+ const agentsDir = this.getAgentsDir();
1204
+
1205
+ // Track which agent IDs we've already processed
1206
+ const processedAgentIds = new Set();
1207
+ const agents = [];
1208
+
1209
+ // First, process agents from the index
1210
+ for (const [agentId, info] of Object.entries(agentIndex)) {
1211
+ // Skip invalid or undefined entries
1212
+ if (!info || !info.name) {
1213
+ continue;
1214
+ }
1215
+
1216
+ processedAgentIds.add(agentId);
1217
+ agents.push({
1218
+ agentId,
1219
+ name: info.name,
1220
+ type: info.type,
1221
+ model: info.model,
1222
+ lastActivity: info.lastActivity,
1223
+ status: info.status,
1224
+ stateFile: info.stateFile,
1225
+ conversationsFile: info.conversationsFile,
1226
+ capabilities: info.capabilities || [],
1227
+ isLoaded: activeAgentIds.includes(agentId),
1228
+ canImport: !activeAgentIds.includes(agentId)
1229
+ });
1230
+ }
1231
+
1232
+ // Second, scan the agents directory for any agents not in the index
1233
+ try {
1234
+ const files = await fs.readdir(agentsDir);
1235
+ const stateFiles = files.filter(f => f.endsWith('-state.json'));
1236
+
1237
+ let indexUpdated = false;
1238
+
1239
+ for (const stateFile of stateFiles) {
1240
+ // Extract agent ID from filename: agent-{agentId}-state.json
1241
+ const match = stateFile.match(/^agent-(.+)-state\.json$/);
1242
+ if (!match) continue;
1243
+
1244
+ const agentId = match[1];
1245
+ if (processedAgentIds.has(agentId)) continue;
1246
+
1247
+ // Found an agent not in the index - load its state
1248
+ try {
1249
+ const statePath = path.join(agentsDir, stateFile);
1250
+ const stateData = await this.loadJSON(statePath);
1251
+ const state = stateData.state || stateData;
1252
+
1253
+ // Build agent info from state file
1254
+ const agentInfo = {
1255
+ agentId,
1256
+ name: state.name || stateData.name || `Recovered Agent ${agentId.slice(-8)}`,
1257
+ type: state.type || 'user-created',
1258
+ model: state.currentModel || state.preferredModel || 'unknown',
1259
+ lastActivity: state.lastActivity || stateData.timestamp || null,
1260
+ status: state.status || 'idle',
1261
+ stateFile: `agents/${stateFile}`,
1262
+ conversationsFile: `agents/agent-${agentId}-conversations.json`,
1263
+ capabilities: state.capabilities || [],
1264
+ isLoaded: activeAgentIds.includes(agentId),
1265
+ canImport: !activeAgentIds.includes(agentId)
1266
+ };
1267
+
1268
+ agents.push(agentInfo);
1269
+ processedAgentIds.add(agentId);
1270
+
1271
+ // Update the index with this recovered agent
1272
+ agentIndex[agentId] = {
1273
+ name: agentInfo.name,
1274
+ type: agentInfo.type,
1275
+ stateFile: agentInfo.stateFile,
1276
+ conversationsFile: agentInfo.conversationsFile,
1277
+ lastActivity: agentInfo.lastActivity,
1278
+ model: agentInfo.model,
1279
+ status: agentInfo.status,
1280
+ capabilities: agentInfo.capabilities
1281
+ };
1282
+ indexUpdated = true;
1283
+
1284
+ this.logger.info(`Recovered agent from disk: ${agentInfo.name} (${agentId})`);
1285
+ } catch (err) {
1286
+ this.logger.warn(`Failed to recover agent from ${stateFile}: ${err.message}`);
1287
+ }
1288
+ }
1289
+
1290
+ // Save the updated index if we found missing agents
1291
+ if (indexUpdated) {
1292
+ const indexFile = path.join(this.stateDirectory, this.stateFiles.agentIndex);
1293
+ await this.saveJSON(indexFile, agentIndex);
1294
+ this.logger.info(`Updated agent index with ${agents.length - Object.keys(agentIndex).length + Object.keys(processedAgentIds).size} recovered agents`);
1295
+ }
1296
+ } catch (err) {
1297
+ this.logger.warn(`Failed to scan agents directory: ${err.message}`);
1298
+ }
1299
+
1300
+ // Sort by last activity (most recent first)
1301
+ agents.sort((a, b) => {
1302
+ const dateA = a.lastActivity ? new Date(a.lastActivity) : new Date(0);
1303
+ const dateB = b.lastActivity ? new Date(b.lastActivity) : new Date(0);
1304
+ return dateB - dateA;
1305
+ });
1306
+
1307
+ // Enrich agents with firstUserMessage snippet
1308
+ await this._enrichAgentsWithSnippets(agents, agentPool);
1309
+
1310
+ this.logger.info(`Found ${agents.length} available agents (${agents.filter(a => a.isLoaded).length} active, ${agents.filter(a => !a.isLoaded).length} archived)`);
1311
+
1312
+ return agents;
1313
+ } catch (error) {
1314
+ this.logger.error(`Failed to get available agents: ${error.message}`);
1315
+ throw error;
1316
+ }
1317
+ }
1318
+
1319
+ /**
1320
+ * Enrich agent list with firstUserMessage snippets.
1321
+ * For loaded agents, reads from agentPool. For archived agents, peeks into conversations file.
1322
+ */
1323
+ async _enrichAgentsWithSnippets(agents, agentPool) {
1324
+ const extractSnippet = (messages) => {
1325
+ if (!messages || messages.length === 0) return null;
1326
+ const firstUser = messages.find(m =>
1327
+ m.role === 'user' && m.content && m.type !== 'task-boundary'
1328
+ );
1329
+ if (!firstUser) return null;
1330
+ const text = typeof firstUser.content === 'string'
1331
+ ? firstUser.content
1332
+ : Array.isArray(firstUser.content)
1333
+ ? firstUser.content.filter(b => b.type === 'text').map(b => b.text).join('\n')
1334
+ : null;
1335
+ if (!text) return null;
1336
+ const lines = text.split('\n').filter(l => l.trim());
1337
+ const snippet = lines.slice(0, 2).join('\n');
1338
+ return snippet.length > 120 ? snippet.slice(0, 117) + '...' : snippet;
1339
+ };
1340
+
1341
+ for (const agent of agents) {
1342
+ try {
1343
+ if (agent.isLoaded && agentPool) {
1344
+ // For loaded agents, get from the in-memory agent
1345
+ const liveAgent = await agentPool.getAgent(agent.agentId);
1346
+ if (liveAgent) {
1347
+ agent.firstUserMessage = extractSnippet(liveAgent.conversations?.full?.messages);
1348
+ continue;
1349
+ }
1350
+ }
1351
+ // For archived agents, peek into the conversations file on disk
1352
+ if (agent.conversationsFile) {
1353
+ const convPath = path.join(this.stateDirectory, agent.conversationsFile);
1354
+ try {
1355
+ const convData = await this.loadJSON(convPath);
1356
+ const messages = convData?.conversations?.full?.messages || convData?.full?.messages;
1357
+ agent.firstUserMessage = extractSnippet(messages);
1358
+ } catch {
1359
+ // File may not exist — that's fine
1360
+ }
1361
+ }
1362
+ } catch {
1363
+ // Non-critical — just skip this agent's snippet
1364
+ }
1365
+ }
1366
+ }
1367
+
1368
+ /**
1369
+ * Get agent metadata without full restoration (lightweight preview)
1370
+ * @param {string} agentId - Agent ID
1371
+ * @param {string} projectDir - Project directory path
1372
+ * @returns {Promise<Object>} Agent metadata for preview
1373
+ */
1374
+ async getAgentMetadata(agentId, projectDir) {
1375
+ try {
1376
+ // Load agent index
1377
+ const agentIndex = await this.loadAgentIndex(projectDir);
1378
+ const agentInfo = agentIndex[agentId];
1379
+
1380
+ if (!agentInfo) {
1381
+ throw new Error(`Agent ${agentId} not found in index`);
1382
+ }
1383
+
1384
+ // Load just the state file (lightweight)
1385
+ const stateDir = this.getStateDir(projectDir);
1386
+ const stateFile = path.join(stateDir, agentInfo.stateFile);
1387
+ const conversationsFile = path.join(stateDir, agentInfo.conversationsFile);
1388
+
1389
+ // Check if files exist
1390
+ const stateExists = await fs.access(stateFile).then(() => true).catch(() => false);
1391
+ const conversationsExist = await fs.access(conversationsFile).then(() => true).catch(() => false);
1392
+
1393
+ if (!stateExists) {
1394
+ throw new Error(`State file not found for agent ${agentId}`);
1395
+ }
1396
+
1397
+ // Load state
1398
+ const stateData = await this.loadJSON(stateFile);
1399
+ const state = stateData.state || {};
1400
+
1401
+ // Load conversation count without loading full messages (for performance)
1402
+ let messageCount = 0;
1403
+ let lastMessage = null;
1404
+ if (conversationsExist) {
1405
+ try {
1406
+ const conversations = await this.loadJSON(conversationsFile);
1407
+ messageCount = Array.isArray(conversations) ? conversations.length : 0;
1408
+
1409
+ // Get last message for preview
1410
+ if (messageCount > 0) {
1411
+ const lastMsg = conversations[conversations.length - 1];
1412
+ lastMessage = lastMsg?.content?.substring(0, 100) || null;
1413
+ }
1414
+ } catch (error) {
1415
+ this.logger.warn(`Failed to load conversations for ${agentId}: ${error.message}`);
1416
+ }
1417
+ }
1418
+
1419
+ const metadata = {
1420
+ agentId,
1421
+ name: agentInfo.name || state.name,
1422
+ model: agentInfo.model || state.preferredModel || state.currentModel,
1423
+ lastActivity: agentInfo.lastActivity,
1424
+ status: agentInfo.status,
1425
+ capabilities: state.capabilities || [],
1426
+ messageCount,
1427
+ lastMessage,
1428
+ taskCount: state.taskList?.tasks?.length || 0,
1429
+ createdAt: state.createdAt,
1430
+ workingDirectory: state.directoryAccess?.workingDirectory,
1431
+ mode: state.mode,
1432
+ systemPrompt: state.originalSystemPrompt
1433
+ };
1434
+
1435
+ this.logger.info(`Loaded metadata for agent ${agentId}: ${metadata.messageCount} messages, ${metadata.taskCount} tasks`);
1436
+
1437
+ return metadata;
1438
+ } catch (error) {
1439
+ this.logger.error(`Failed to get agent metadata for ${agentId}: ${error.message}`);
1440
+ throw error;
1441
+ }
1442
+ }
1443
+
1444
+ /**
1445
+ * Import archived agent from filesystem and add to agent pool
1446
+ * @param {string} agentId - Agent ID to import
1447
+ * @param {string} projectDir - Project directory path
1448
+ * @param {Object} agentPool - Agent pool instance
1449
+ * @returns {Promise<Object>} Imported agent object
1450
+ */
1451
+ async importArchivedAgent(agentId, projectDir, agentPool) {
1452
+ try {
1453
+ // Validate agent ID format for security
1454
+ const AGENT_ID_REGEX = /^agent-[a-z0-9-]+-\d+$/;
1455
+ if (!AGENT_ID_REGEX.test(agentId)) {
1456
+ throw new Error('Invalid agent ID format');
1457
+ }
1458
+
1459
+ // Check if already loaded in agent pool
1460
+ if (agentPool && await agentPool.getAgent(agentId)) {
1461
+ throw new Error(`Agent ${agentId} is already loaded. Use switchAgent() instead.`);
1462
+ }
1463
+
1464
+ // Load from agent index
1465
+ const agentIndex = await this.loadAgentIndex(projectDir);
1466
+ const agentInfo = agentIndex[agentId];
1467
+
1468
+ if (!agentInfo) {
1469
+ throw new Error(`Agent ${agentId} not found in index`);
1470
+ }
1471
+
1472
+ this.logger.info(`Importing archived agent: ${agentId} (${agentInfo.name})`);
1473
+
1474
+ // Restore agent using existing restore logic
1475
+ const agent = await this.restoreAgent(agentId, agentInfo, projectDir);
1476
+
1477
+ // Update agent's last activity
1478
+ agent.lastActivity = new Date().toISOString();
1479
+
1480
+ // Add to agent pool if provided
1481
+ if (agentPool) {
1482
+ agentPool.agents.set(agent.id, agent);
1483
+ agentPool._updateAgentDirectory(agent);
1484
+ this.logger.info(`Agent ${agentId} added to agent pool`);
1485
+ }
1486
+
1487
+ // Update agent index with new last activity
1488
+ await this.updateAgentIndex(agent, projectDir);
1489
+
1490
+ this.logger.info(`Successfully imported agent ${agentId}: ${agent.name}`);
1491
+
1492
+ return agent;
1493
+ } catch (error) {
1494
+ this.logger.error(`Failed to import agent ${agentId}: ${error.message}`);
1495
+ throw error;
1496
+ }
1497
+ }
1498
+ }
1499
+
1500
+ export default StateManager;