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,2836 @@
1
+ /**
2
+ * TaskManagerTool - Manages task list for agent autonomous operation
3
+ *
4
+ * Purpose:
5
+ * - Allows agents to create, update, and manage their own TODO list
6
+ * - Provides task tracking for agent-mode scheduling decisions
7
+ * - Ensures agents only consume resources when they have actual work
8
+ */
9
+
10
+ import { BaseTool } from './baseTool.js';
11
+ import { v4 as uuidv4 } from 'uuid';
12
+
13
+ class TaskManagerTool extends BaseTool {
14
+ constructor(config = {}) {
15
+ super({
16
+ name: 'taskmanager',
17
+ description: config.description || 'Task management tool for organizing and tracking work',
18
+ ...config
19
+ });
20
+
21
+ this.supportedActions = ['create', 'update', 'list', 'complete', 'cancel', 'clear', 'depend', 'relate', 'subtask', 'prioritize', 'template', 'progress', 'analytics', 'sync'];
22
+ this.taskStatuses = ['pending', 'in_progress', 'blocked', 'completed', 'cancelled'];
23
+ this.taskPriorities = ['urgent', 'high', 'medium', 'low'];
24
+ this.dependencyTypes = ['blocks', 'relates', 'subtask', 'parent'];
25
+
26
+ // Phase 3.4: Progress tracking stages
27
+ this.progressStages = ['not_started', 'planning', 'in_development', 'testing', 'review', 'completed'];
28
+ this.milestoneTypes = ['checkpoint', 'deliverable', 'review_point', 'dependency_gate'];
29
+
30
+ // Phase 3.2: Priority scoring weights
31
+ this.priorityWeights = {
32
+ blocking: 3.0, // Tasks that block others
33
+ age: 1.5, // Older tasks get higher priority
34
+ userPriority: 2.0, // User-defined priority
35
+ contextSwitching: 1.2, // Reduce context switching penalty
36
+ dependency: 1.8 // Tasks with many dependencies
37
+ };
38
+
39
+ // Phase 3.3: Built-in task templates
40
+ this.taskTemplates = {
41
+ 'web-app-development': {
42
+ name: 'Web Application Development',
43
+ description: 'Complete workflow for building a web application',
44
+ category: 'development',
45
+ tasks: [
46
+ {
47
+ title: 'Project Setup & Planning',
48
+ description: 'Initialize project structure, configure tools, and plan architecture',
49
+ priority: 'high',
50
+ dependencies: []
51
+ },
52
+ {
53
+ title: 'Database Design & Setup',
54
+ description: 'Design database schema, create tables, and set up connections',
55
+ priority: 'high',
56
+ dependencies: ['Project Setup & Planning']
57
+ },
58
+ {
59
+ title: 'Backend API Development',
60
+ description: 'Implement REST API endpoints and business logic',
61
+ priority: 'high',
62
+ dependencies: ['Database Design & Setup']
63
+ },
64
+ {
65
+ title: 'Frontend Development',
66
+ description: 'Build user interface components and implement client-side logic',
67
+ priority: 'medium',
68
+ dependencies: ['Backend API Development']
69
+ },
70
+ {
71
+ title: 'Testing & Quality Assurance',
72
+ description: 'Write and run unit tests, integration tests, and perform QA',
73
+ priority: 'medium',
74
+ dependencies: ['Frontend Development']
75
+ },
76
+ {
77
+ title: 'Deployment & Launch',
78
+ description: 'Deploy to production environment and monitor launch',
79
+ priority: 'high',
80
+ dependencies: ['Testing & Quality Assurance']
81
+ }
82
+ ]
83
+ },
84
+ 'api-integration': {
85
+ name: 'API Integration',
86
+ description: 'Standard workflow for integrating with external APIs',
87
+ category: 'integration',
88
+ tasks: [
89
+ {
90
+ title: 'API Research & Documentation Review',
91
+ description: 'Study API documentation, authentication, and rate limits',
92
+ priority: 'high',
93
+ dependencies: []
94
+ },
95
+ {
96
+ title: 'Authentication Setup',
97
+ description: 'Implement API key management and authentication flow',
98
+ priority: 'high',
99
+ dependencies: ['API Research & Documentation Review']
100
+ },
101
+ {
102
+ title: 'Core Integration Implementation',
103
+ description: 'Build API client and implement main integration logic',
104
+ priority: 'high',
105
+ dependencies: ['Authentication Setup']
106
+ },
107
+ {
108
+ title: 'Error Handling & Retry Logic',
109
+ description: 'Implement robust error handling and retry mechanisms',
110
+ priority: 'medium',
111
+ dependencies: ['Core Integration Implementation']
112
+ },
113
+ {
114
+ title: 'Testing & Validation',
115
+ description: 'Test integration with various scenarios and edge cases',
116
+ priority: 'medium',
117
+ dependencies: ['Error Handling & Retry Logic']
118
+ }
119
+ ]
120
+ },
121
+ 'bug-fix': {
122
+ name: 'Bug Fix Workflow',
123
+ description: 'Systematic approach to identifying and fixing bugs',
124
+ category: 'maintenance',
125
+ tasks: [
126
+ {
127
+ title: 'Bug Reproduction & Analysis',
128
+ description: 'Reproduce the bug and analyze root cause',
129
+ priority: 'urgent',
130
+ dependencies: []
131
+ },
132
+ {
133
+ title: 'Fix Implementation',
134
+ description: 'Implement the bug fix with minimal side effects',
135
+ priority: 'urgent',
136
+ dependencies: ['Bug Reproduction & Analysis']
137
+ },
138
+ {
139
+ title: 'Testing & Verification',
140
+ description: 'Test fix and verify no regressions introduced',
141
+ priority: 'high',
142
+ dependencies: ['Fix Implementation']
143
+ },
144
+ {
145
+ title: 'Documentation Update',
146
+ description: 'Update documentation if behavior changed',
147
+ priority: 'low',
148
+ dependencies: ['Testing & Verification']
149
+ }
150
+ ]
151
+ },
152
+ 'feature-development': {
153
+ name: 'Feature Development',
154
+ description: 'End-to-end feature development workflow',
155
+ category: 'development',
156
+ tasks: [
157
+ {
158
+ title: 'Requirements Analysis',
159
+ description: 'Analyze requirements and create technical specification',
160
+ priority: 'high',
161
+ dependencies: []
162
+ },
163
+ {
164
+ title: 'Design & Architecture',
165
+ description: 'Design system architecture and user interface',
166
+ priority: 'high',
167
+ dependencies: ['Requirements Analysis']
168
+ },
169
+ {
170
+ title: 'Backend Implementation',
171
+ description: 'Implement backend logic and data models',
172
+ priority: 'high',
173
+ dependencies: ['Design & Architecture']
174
+ },
175
+ {
176
+ title: 'Frontend Implementation',
177
+ description: 'Build user interface and integrate with backend',
178
+ priority: 'medium',
179
+ dependencies: ['Backend Implementation']
180
+ },
181
+ {
182
+ title: 'Testing & Documentation',
183
+ description: 'Write tests and update documentation',
184
+ priority: 'medium',
185
+ dependencies: ['Frontend Implementation']
186
+ }
187
+ ]
188
+ }
189
+ };
190
+ }
191
+
192
+ /**
193
+ * Get basic tool description (required by BaseTool)
194
+ * @returns {string} Tool description
195
+ */
196
+ getDescription() {
197
+ return `
198
+ Task Manager Tool: Organize and track work with TODO lists for agent-mode scheduling.
199
+
200
+ **CRITICAL**: Maintain your task list to remain active in agent mode!
201
+
202
+ USAGE:
203
+ \`\`\`json
204
+ {
205
+ "toolId": "taskmanager",
206
+ "actions": [{"type": "action-name", ...params}]
207
+ }
208
+ \`\`\`
209
+
210
+ ACTIONS:
211
+ - **sync**: Manage entire task list at once (RECOMMENDED)
212
+ - **create**: Create task (title, description, priority)
213
+ - **update**: Update task (taskId, status, priority)
214
+ - **list**: List all tasks
215
+ - **complete**: Mark task done (taskId)
216
+ - **cancel**: Cancel task (taskId)
217
+ - **clear**: Clear completed/cancelled tasks
218
+
219
+ EXAMPLES:
220
+
221
+ Sync task list (RECOMMENDED):
222
+ \`\`\`json
223
+ {
224
+ "toolId": "taskmanager",
225
+ "actions": [{
226
+ "type": "sync",
227
+ "tasks": [
228
+ {"title": "Analyze requirements", "status": "completed", "priority": "high"},
229
+ {"title": "Design schema", "status": "in_progress", "priority": "high"},
230
+ {"title": "Implement API", "status": "pending", "priority": "medium"}
231
+ ]
232
+ }]
233
+ }
234
+ \`\`\`
235
+
236
+ Create a task:
237
+ \`\`\`json
238
+ {
239
+ "toolId": "taskmanager",
240
+ "actions": [{
241
+ "type": "create",
242
+ "title": "Implement authentication",
243
+ "description": "Add login and signup",
244
+ "priority": "high"
245
+ }]
246
+ }
247
+ \`\`\`
248
+
249
+ List tasks:
250
+ \`\`\`json
251
+ {"toolId": "taskmanager", "actions": [{"type": "list"}]}
252
+ \`\`\`
253
+
254
+ Complete a task:
255
+ \`\`\`json
256
+ {"toolId": "taskmanager", "actions": [{"type": "complete", "taskId": "task-123"}]}
257
+ \`\`\`
258
+
259
+ WORKFLOW:
260
+ 1. List tasks to see current state
261
+ 2. Work on tasks
262
+ 3. Mark tasks complete when done
263
+
264
+ **MANDATORY**: Complete tasks when finished or you'll loop forever!
265
+ `;
266
+ }
267
+
268
+ /**
269
+ * Parse parameters from XML tag format
270
+ * Unwraps values from tag parser's {value, attributes} format
271
+ * @param {Object} content - Raw parameters from tag parser or string content
272
+ * @returns {Object} Parsed parameters with unwrapped values
273
+ */
274
+ parseParameters(content) {
275
+ // If content is a string, return as-is for legacy support
276
+ if (typeof content === 'string') {
277
+ return { rawContent: content };
278
+ }
279
+
280
+ // If content is already an object, unwrap tag parser format
281
+ if (typeof content === 'object' && content !== null) {
282
+ const unwrapped = {};
283
+
284
+ for (const [key, value] of Object.entries(content)) {
285
+ // Check if this is tag parser format: {value: "...", attributes: {}}
286
+ if (value && typeof value === 'object' && 'value' in value) {
287
+ unwrapped[key] = value.value;
288
+ } else {
289
+ // Keep as-is if not wrapped
290
+ unwrapped[key] = value;
291
+ }
292
+ }
293
+
294
+ return unwrapped;
295
+ }
296
+
297
+ return content;
298
+ }
299
+
300
+ /**
301
+ * Execute task management action
302
+ * @param {Object} params - Tool arguments
303
+ * @param {Object} context - Execution context
304
+ * @returns {Promise<Object>} Execution result
305
+ */
306
+ async execute(params, context) {
307
+ try {
308
+ // CRITICAL FIX: Unwrap tag parser format {value, attributes}
309
+ // The messageProcessor passes params with wrapped values from parseXMLParameters
310
+ // We need to unwrap them before processing
311
+ const unwrappedParams = {};
312
+ for (const [key, value] of Object.entries(params)) {
313
+ if (value && typeof value === 'object' && 'value' in value) {
314
+ // Tag parser wrapped format: {value: "...", attributes: {}}
315
+ unwrappedParams[key] = value.value;
316
+ } else {
317
+ // Already unwrapped or direct value
318
+ unwrappedParams[key] = value;
319
+ }
320
+ }
321
+
322
+ // Use unwrapped params for all subsequent processing
323
+ params = unwrappedParams;
324
+
325
+ // CRITICAL FIX: Handle the documented "actions" array format
326
+ // Documentation shows: {"toolId": "taskmanager", "actions": [{"type": "create", ...}]}
327
+ // But code was expecting: {"action": "create", ...}
328
+ // This normalizes both formats to work correctly
329
+ if (params.actions && Array.isArray(params.actions) && params.actions.length > 0) {
330
+ let firstAction = params.actions[0];
331
+
332
+ // Deep unwrap the first action if it contains wrapped values
333
+ // This handles cases where array elements are also wrapped: {type: {value: "sync", attributes: {}}}
334
+ if (firstAction && typeof firstAction === 'object') {
335
+ const unwrappedAction = {};
336
+ for (const [key, value] of Object.entries(firstAction)) {
337
+ if (value && typeof value === 'object' && 'value' in value) {
338
+ unwrappedAction[key] = value.value;
339
+ } else {
340
+ unwrappedAction[key] = value;
341
+ }
342
+ }
343
+ firstAction = unwrappedAction;
344
+ }
345
+
346
+ // Extract action type from 'type' field in the actions array
347
+ if (firstAction.type && !params.action) {
348
+ params.action = firstAction.type;
349
+ // Merge all other properties from the action object into params
350
+ for (const [key, value] of Object.entries(firstAction)) {
351
+ if (key !== 'type' && !(key in params)) {
352
+ params[key] = value;
353
+ }
354
+ }
355
+ }
356
+ }
357
+
358
+ const { agentId, agentName } = context;
359
+
360
+ if (!agentId) {
361
+ throw new Error('Agent ID is required for task management');
362
+ }
363
+
364
+ // Get agent from pool
365
+ const agent = await context.agentPool.getAgent(agentId);
366
+ if (!agent) {
367
+ throw new Error(`Agent not found: ${agentId}`);
368
+ }
369
+
370
+ // Initialize taskList if it doesn't exist (for backwards compatibility)
371
+ if (!agent.taskList) {
372
+ agent.taskList = {
373
+ tasks: [],
374
+ lastUpdated: new Date().toISOString()
375
+ };
376
+ }
377
+
378
+ const action = params.action?.toLowerCase();
379
+ if (!this.supportedActions.includes(action)) {
380
+ throw new Error(`Unsupported action: ${action}. Supported: ${this.supportedActions.join(', ')}`);
381
+ }
382
+
383
+ let result;
384
+ switch (action) {
385
+ case 'create':
386
+ result = await this.createTask(agent, params);
387
+ break;
388
+ case 'update':
389
+ result = await this.updateTask(agent, params);
390
+ break;
391
+ case 'list':
392
+ result = await this.listTasks(agent, params);
393
+ break;
394
+ case 'complete':
395
+ result = await this.completeTask(agent, params);
396
+ break;
397
+ case 'cancel':
398
+ result = await this.cancelTask(agent, params);
399
+ break;
400
+ case 'clear':
401
+ result = await this.clearCompletedTasks(agent, params);
402
+ break;
403
+ case 'depend':
404
+ result = await this.createDependency(agent, params);
405
+ break;
406
+ case 'relate':
407
+ result = await this.relateTask(agent, params);
408
+ break;
409
+ case 'subtask':
410
+ result = await this.createSubtask(agent, params);
411
+ break;
412
+ case 'prioritize':
413
+ result = await this.intelligentPrioritization(agent, params);
414
+ break;
415
+ case 'template':
416
+ result = await this.manageTemplates(agent, params);
417
+ break;
418
+ case 'progress':
419
+ result = await this.trackProgress(agent, params);
420
+ break;
421
+ case 'analytics':
422
+ result = await this.generateAnalytics(agent, params);
423
+ break;
424
+ case 'sync':
425
+ result = await this.syncTasks(agent, params);
426
+ break;
427
+ default:
428
+ throw new Error(`Unknown action: ${action}`);
429
+ }
430
+
431
+ // Update the agent's lastActivity
432
+ agent.lastActivity = new Date().toISOString();
433
+ agent.taskList.lastUpdated = new Date().toISOString();
434
+
435
+ // Persist the agent state
436
+ await context.agentPool.persistAgentState(agentId);
437
+
438
+ const pendingCount = agent.taskList.tasks.filter(t => t.status === 'pending' || t.status === 'in_progress').length;
439
+
440
+ this.logger?.info(`TaskManager action executed: ${action}`, {
441
+ agentId,
442
+ agentName,
443
+ action,
444
+ taskCount: agent.taskList.tasks.length,
445
+ pendingTasks: agent.taskList.tasks.filter(t => t.status === 'pending').length,
446
+ inProgressTasks: agent.taskList.tasks.filter(t => t.status === 'in_progress').length
447
+ });
448
+
449
+ // When no actionable tasks remain, set TTL to give agent one more cycle to react
450
+ // This allows the agent to call job-done or create new tasks before becoming idle
451
+ if (pendingCount === 0) {
452
+ agent.ttl = 1;
453
+ await context.agentPool.persistAgentState(agentId);
454
+ this.logger?.debug(`TTL set to 1 for agent ${agentId} - no remaining tasks`);
455
+ }
456
+
457
+ // When no actionable tasks remain, prompt the agent to decide next steps
458
+ const noTasksHint = pendingCount === 0
459
+ ? '\n\n[No remaining tasks] Have you fulfilled the user\'s request? If so, call job-done with a summary. Otherwise, update your task list to reflect what still needs to be done.'
460
+ : '';
461
+
462
+ return {
463
+ success: true,
464
+ action,
465
+ result,
466
+ summary: this.generateTaskSummary(agent.taskList) + noTasksHint
467
+ };
468
+
469
+ } catch (error) {
470
+ this.logger?.error('TaskManager execution failed', {
471
+ error: error.message,
472
+ context,
473
+ params
474
+ });
475
+
476
+ return {
477
+ success: false,
478
+ error: error.message
479
+ };
480
+ }
481
+ }
482
+
483
+ /**
484
+ * Create a new task
485
+ * @private
486
+ */
487
+ async createTask(agent, params) {
488
+ const { title, description = '', priority = 'medium' } = params;
489
+
490
+ if (!title) {
491
+ throw new Error('Task title is required');
492
+ }
493
+
494
+ if (priority && !this.taskPriorities.includes(priority.toLowerCase())) {
495
+ throw new Error(`Invalid priority: ${priority}. Must be: ${this.taskPriorities.join(', ')}`);
496
+ }
497
+
498
+ const task = {
499
+ id: `task-${uuidv4()}`,
500
+ title,
501
+ description,
502
+ status: 'pending',
503
+ priority: priority.toLowerCase(),
504
+ createdAt: new Date().toISOString(),
505
+ updatedAt: new Date().toISOString()
506
+ };
507
+
508
+ agent.taskList.tasks.push(task);
509
+
510
+ return {
511
+ message: 'Task created successfully',
512
+ task
513
+ };
514
+ }
515
+
516
+ /**
517
+ * Sync entire task list (Claude Code style batch management)
518
+ * @private
519
+ */
520
+ async syncTasks(agent, params) {
521
+ let { tasks } = params;
522
+
523
+ // Parse tasks if provided as JSON string
524
+ if (typeof tasks === 'string') {
525
+ try {
526
+ tasks = JSON.parse(tasks);
527
+ } catch (error) {
528
+ throw new Error(`Invalid tasks JSON: ${error.message}`);
529
+ }
530
+ }
531
+
532
+ if (!Array.isArray(tasks)) {
533
+ throw new Error('Tasks must be an array');
534
+ }
535
+
536
+ if (tasks.length === 0) {
537
+ throw new Error('Tasks array cannot be empty');
538
+ }
539
+
540
+ const timestamp = new Date().toISOString();
541
+ const existingTasks = agent.taskList.tasks || [];
542
+ const updatedTasks = [];
543
+ const createdTasks = [];
544
+ const matchedIds = new Set();
545
+
546
+ // Helper: fuzzy match task by title
547
+ const findExistingTask = (title) => {
548
+ const normalizedTitle = title.toLowerCase().trim();
549
+ return existingTasks.find(t =>
550
+ t.title.toLowerCase().trim() === normalizedTitle &&
551
+ !matchedIds.has(t.id)
552
+ );
553
+ };
554
+
555
+ // Validate and process each task
556
+ for (const taskData of tasks) {
557
+ if (!taskData.title) {
558
+ throw new Error('Each task must have a title');
559
+ }
560
+
561
+ const status = (taskData.status || 'pending').toLowerCase();
562
+ const priority = (taskData.priority || 'medium').toLowerCase();
563
+
564
+ // Validate status
565
+ if (!this.taskStatuses.includes(status)) {
566
+ throw new Error(`Invalid status "${status}" for task "${taskData.title}". Must be: ${this.taskStatuses.join(', ')}`);
567
+ }
568
+
569
+ // Validate priority
570
+ if (!this.taskPriorities.includes(priority)) {
571
+ throw new Error(`Invalid priority "${priority}" for task "${taskData.title}". Must be: ${this.taskPriorities.join(', ')}`);
572
+ }
573
+
574
+ // Try to match with existing task
575
+ const existingTask = findExistingTask(taskData.title);
576
+
577
+ if (existingTask) {
578
+ // Update existing task
579
+ existingTask.status = status;
580
+ existingTask.priority = priority;
581
+ if (taskData.description !== undefined) {
582
+ existingTask.description = taskData.description;
583
+ }
584
+ existingTask.updatedAt = timestamp;
585
+
586
+ updatedTasks.push(existingTask);
587
+ matchedIds.add(existingTask.id);
588
+ } else {
589
+ // Create new task
590
+ const newTask = {
591
+ id: `task-${uuidv4()}`,
592
+ title: taskData.title,
593
+ description: taskData.description || '',
594
+ status: status,
595
+ priority: priority,
596
+ createdAt: timestamp,
597
+ updatedAt: timestamp,
598
+ source: 'sync'
599
+ };
600
+
601
+ createdTasks.push(newTask);
602
+ }
603
+ }
604
+
605
+ // Replace task list with synced tasks
606
+ agent.taskList.tasks = [...updatedTasks, ...createdTasks];
607
+
608
+ // Ensure only one task is in_progress
609
+ const inProgressTasks = agent.taskList.tasks.filter(t => t.status === 'in_progress');
610
+ if (inProgressTasks.length > 1) {
611
+ // Keep only the first in_progress task, set others to pending
612
+ for (let i = 1; i < inProgressTasks.length; i++) {
613
+ inProgressTasks[i].status = 'pending';
614
+ }
615
+ }
616
+
617
+ // Auto-set first pending task to in_progress if no task is in_progress
618
+ if (inProgressTasks.length === 0) {
619
+ const firstPending = agent.taskList.tasks.find(t => t.status === 'pending');
620
+ if (firstPending) {
621
+ firstPending.status = 'in_progress';
622
+ firstPending.updatedAt = timestamp;
623
+ }
624
+ }
625
+
626
+ agent.taskList.lastUpdated = timestamp;
627
+
628
+ return {
629
+ message: 'Task list synchronized successfully',
630
+ summary: {
631
+ total: agent.taskList.tasks.length,
632
+ created: createdTasks.length,
633
+ updated: updatedTasks.length,
634
+ removed: existingTasks.length - matchedIds.size,
635
+ pending: agent.taskList.tasks.filter(t => t.status === 'pending').length,
636
+ inProgress: agent.taskList.tasks.filter(t => t.status === 'in_progress').length,
637
+ completed: agent.taskList.tasks.filter(t => t.status === 'completed').length,
638
+ cancelled: agent.taskList.tasks.filter(t => t.status === 'cancelled').length
639
+ },
640
+ tasks: agent.taskList.tasks.map(t => ({
641
+ id: t.id,
642
+ title: t.title,
643
+ status: t.status,
644
+ priority: t.priority
645
+ }))
646
+ };
647
+ }
648
+
649
+ /**
650
+ * Update an existing task
651
+ * @private
652
+ */
653
+ async updateTask(agent, params) {
654
+ const { taskId, status, priority, title, description } = params;
655
+
656
+ if (!taskId) {
657
+ throw new Error('Task ID is required for update');
658
+ }
659
+
660
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
661
+ if (!task) {
662
+ throw new Error(`Task not found: ${taskId}`);
663
+ }
664
+
665
+ if (status) {
666
+ if (!this.taskStatuses.includes(status.toLowerCase())) {
667
+ throw new Error(`Invalid status: ${status}. Must be: ${this.taskStatuses.join(', ')}`);
668
+ }
669
+ task.status = status.toLowerCase();
670
+ }
671
+
672
+ if (priority) {
673
+ if (!this.taskPriorities.includes(priority.toLowerCase())) {
674
+ throw new Error(`Invalid priority: ${priority}. Must be: ${this.taskPriorities.join(', ')}`);
675
+ }
676
+ task.priority = priority.toLowerCase();
677
+ }
678
+
679
+ if (title !== undefined) task.title = title;
680
+ if (description !== undefined) task.description = description;
681
+
682
+ task.updatedAt = new Date().toISOString();
683
+
684
+ return {
685
+ message: 'Task updated successfully',
686
+ task
687
+ };
688
+ }
689
+
690
+ /**
691
+ * List all tasks
692
+ * @private
693
+ */
694
+ async listTasks(agent, params) {
695
+ const { status, priority } = params;
696
+ let tasks = [...agent.taskList.tasks];
697
+
698
+ // Filter by status if specified
699
+ if (status) {
700
+ if (!this.taskStatuses.includes(status.toLowerCase())) {
701
+ throw new Error(`Invalid status filter: ${status}`);
702
+ }
703
+ tasks = tasks.filter(t => t.status === status.toLowerCase());
704
+ }
705
+
706
+ // Filter by priority if specified
707
+ if (priority) {
708
+ if (!this.taskPriorities.includes(priority.toLowerCase())) {
709
+ throw new Error(`Invalid priority filter: ${priority}`);
710
+ }
711
+ tasks = tasks.filter(t => t.priority === priority.toLowerCase());
712
+ }
713
+
714
+ // Sort by priority (high first) then by creation date
715
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
716
+ tasks.sort((a, b) => {
717
+ const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
718
+ if (priorityDiff !== 0) return priorityDiff;
719
+ return new Date(a.createdAt) - new Date(b.createdAt);
720
+ });
721
+
722
+ return {
723
+ totalTasks: tasks.length,
724
+ tasks,
725
+ summary: {
726
+ pending: tasks.filter(t => t.status === 'pending').length,
727
+ in_progress: tasks.filter(t => t.status === 'in_progress').length,
728
+ completed: tasks.filter(t => t.status === 'completed').length,
729
+ cancelled: tasks.filter(t => t.status === 'cancelled').length
730
+ }
731
+ };
732
+ }
733
+
734
+ /**
735
+ * Complete a task
736
+ * @private
737
+ */
738
+ async completeTask(agent, params) {
739
+ let { taskId } = params;
740
+
741
+ // If no taskId provided, auto-complete the first in-progress task
742
+ if (!taskId) {
743
+ const inProgressTask = agent.taskList.tasks.find(t => t.status === 'in_progress' || t.status === 'pending');
744
+ if (inProgressTask) {
745
+ taskId = inProgressTask.id;
746
+ this.logger?.info(`Auto-completing current task: ${taskId}`, {
747
+ agentId: agent.id,
748
+ taskTitle: inProgressTask.title
749
+ });
750
+ } else {
751
+ throw new Error('No task ID provided and no in-progress tasks found to complete');
752
+ }
753
+ }
754
+
755
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
756
+ if (!task) {
757
+ throw new Error(`Task not found: ${taskId}`);
758
+ }
759
+
760
+ if (task.status === 'completed') {
761
+ return {
762
+ message: 'Task already completed',
763
+ task
764
+ };
765
+ }
766
+
767
+ task.status = 'completed';
768
+ task.completedAt = new Date().toISOString();
769
+ task.updatedAt = new Date().toISOString();
770
+
771
+ // Phase 3: Trigger dependency updates when task is completed
772
+ if (this.scheduler && typeof this.scheduler.updateDependentTasks === 'function') {
773
+ try {
774
+ await this.scheduler.updateDependentTasks(agent, taskId);
775
+ this.logger?.info(`Triggered dependency update for completed task`, {
776
+ taskId,
777
+ title: task.title
778
+ });
779
+ } catch (error) {
780
+ this.logger?.warn(`Failed to update dependent tasks`, {
781
+ taskId,
782
+ error: error.message
783
+ });
784
+ }
785
+ }
786
+
787
+ const remainingPending = agent.taskList.tasks.filter(
788
+ t => t.status === 'pending' || t.status === 'in_progress'
789
+ ).length;
790
+
791
+ return {
792
+ message: 'Task completed successfully',
793
+ task,
794
+ remainingPendingTasks: remainingPending,
795
+ dependenciesUpdated: !!this.scheduler
796
+ };
797
+ }
798
+
799
+ /**
800
+ * Cancel a task
801
+ * @private
802
+ */
803
+ async cancelTask(agent, params) {
804
+ const { taskId, reason = '' } = params;
805
+
806
+ if (!taskId) {
807
+ throw new Error('Task ID is required');
808
+ }
809
+
810
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
811
+ if (!task) {
812
+ throw new Error(`Task not found: ${taskId}`);
813
+ }
814
+
815
+ task.status = 'cancelled';
816
+ task.cancelledAt = new Date().toISOString();
817
+ task.cancellationReason = reason;
818
+ task.updatedAt = new Date().toISOString();
819
+
820
+ const remainingPending = agent.taskList.tasks.filter(
821
+ t => t.status === 'pending' || t.status === 'in_progress'
822
+ ).length;
823
+
824
+ return {
825
+ message: 'Task cancelled successfully',
826
+ task,
827
+ remainingPendingTasks: remainingPending
828
+ };
829
+ }
830
+
831
+ /**
832
+ * Clear completed and cancelled tasks
833
+ * @private
834
+ */
835
+ async clearCompletedTasks(agent, params) {
836
+ const originalCount = agent.taskList.tasks.length;
837
+
838
+ // Keep only pending and in_progress tasks
839
+ agent.taskList.tasks = agent.taskList.tasks.filter(
840
+ t => t.status === 'pending' || t.status === 'in_progress'
841
+ );
842
+
843
+ const removedCount = originalCount - agent.taskList.tasks.length;
844
+
845
+ return {
846
+ message: `Cleared ${removedCount} completed/cancelled tasks`,
847
+ remainingTasks: agent.taskList.tasks.length,
848
+ removed: removedCount
849
+ };
850
+ }
851
+
852
+ /**
853
+ * Create dependency between tasks (Phase 3)
854
+ * @private
855
+ */
856
+ async createDependency(agent, params) {
857
+ const { taskId, dependsOn, dependencyType = 'blocks' } = params;
858
+
859
+ if (!taskId || !dependsOn) {
860
+ throw new Error('Both taskId and dependsOn are required for creating dependencies');
861
+ }
862
+
863
+ if (!this.dependencyTypes.includes(dependencyType)) {
864
+ throw new Error(`Invalid dependency type: ${dependencyType}. Must be: ${this.dependencyTypes.join(', ')}`);
865
+ }
866
+
867
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
868
+ const dependencyTask = agent.taskList.tasks.find(t => t.id === dependsOn);
869
+
870
+ if (!task) {
871
+ throw new Error(`Task not found: ${taskId}`);
872
+ }
873
+
874
+ if (!dependencyTask) {
875
+ throw new Error(`Dependency task not found: ${dependsOn}`);
876
+ }
877
+
878
+ // Initialize dependencies array if not exists
879
+ if (!task.dependencies) {
880
+ task.dependencies = [];
881
+ }
882
+
883
+ // Check if dependency already exists
884
+ const existingDep = task.dependencies.find(d => d.taskId === dependsOn);
885
+ if (existingDep) {
886
+ return {
887
+ message: 'Dependency already exists',
888
+ dependency: existingDep
889
+ };
890
+ }
891
+
892
+ // Create dependency
893
+ const dependency = {
894
+ taskId: dependsOn,
895
+ type: dependencyType,
896
+ createdAt: new Date().toISOString()
897
+ };
898
+
899
+ task.dependencies.push(dependency);
900
+ task.updatedAt = new Date().toISOString();
901
+
902
+ // If this is a blocking dependency, check if task should be blocked
903
+ if (dependencyType === 'blocks' && dependencyTask.status !== 'completed') {
904
+ task.status = 'blocked';
905
+ }
906
+
907
+ return {
908
+ message: 'Dependency created successfully',
909
+ dependency,
910
+ task
911
+ };
912
+ }
913
+
914
+ /**
915
+ * Create relationship between tasks (non-blocking)
916
+ * @private
917
+ */
918
+ async relateTask(agent, params) {
919
+ return await this.createDependency(agent, { ...params, dependencyType: 'relates' });
920
+ }
921
+
922
+ /**
923
+ * Create subtask relationship
924
+ * @private
925
+ */
926
+ async createSubtask(agent, params) {
927
+ const { parentTaskId, title, description = '', priority = 'medium' } = params;
928
+
929
+ if (!parentTaskId || !title) {
930
+ throw new Error('Parent task ID and title are required for creating subtasks');
931
+ }
932
+
933
+ const parentTask = agent.taskList.tasks.find(t => t.id === parentTaskId);
934
+ if (!parentTask) {
935
+ throw new Error(`Parent task not found: ${parentTaskId}`);
936
+ }
937
+
938
+ // Create the subtask
939
+ const subtask = {
940
+ id: `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
941
+ title,
942
+ description,
943
+ status: 'pending',
944
+ priority: priority.toLowerCase(),
945
+ createdAt: new Date().toISOString(),
946
+ updatedAt: new Date().toISOString(),
947
+ parentTaskId: parentTaskId,
948
+ isSubtask: true,
949
+ source: 'user-created'
950
+ };
951
+
952
+ agent.taskList.tasks.push(subtask);
953
+
954
+ // Initialize subtasks array on parent if not exists
955
+ if (!parentTask.subtasks) {
956
+ parentTask.subtasks = [];
957
+ }
958
+
959
+ parentTask.subtasks.push(subtask.id);
960
+ parentTask.updatedAt = new Date().toISOString();
961
+
962
+ return {
963
+ message: 'Subtask created successfully',
964
+ subtask,
965
+ parentTask
966
+ };
967
+ }
968
+
969
+ /**
970
+ * Template management (Phase 3.3)
971
+ * @private
972
+ */
973
+ async manageTemplates(agent, params) {
974
+ const { mode = 'list', templateId, customTemplate, projectContext } = params;
975
+
976
+ let results = {};
977
+
978
+ if (mode === 'list') {
979
+ // List available templates
980
+ results = await this.listAvailableTemplates(agent);
981
+ } else if (mode === 'apply' && templateId) {
982
+ // Apply a template to create tasks
983
+ results = await this.applyTemplate(agent, templateId, projectContext);
984
+ } else if (mode === 'create' && customTemplate) {
985
+ // Create custom template
986
+ results = await this.createCustomTemplate(agent, customTemplate);
987
+ } else if (mode === 'suggest') {
988
+ // Suggest templates based on existing tasks
989
+ results = await this.suggestTemplates(agent);
990
+ } else {
991
+ throw new Error('Invalid template mode. Use: list, apply, create, or suggest');
992
+ }
993
+
994
+ return {
995
+ message: `Template management completed (${mode})`,
996
+ mode,
997
+ ...results
998
+ };
999
+ }
1000
+
1001
+ /**
1002
+ * List available task templates
1003
+ * @private
1004
+ */
1005
+ async listAvailableTemplates(agent) {
1006
+ const builtInTemplates = Object.entries(this.taskTemplates).map(([id, template]) => ({
1007
+ id,
1008
+ name: template.name,
1009
+ description: template.description,
1010
+ category: template.category,
1011
+ taskCount: template.tasks.length,
1012
+ type: 'built-in'
1013
+ }));
1014
+
1015
+ // Get custom templates from agent's storage
1016
+ const customTemplates = agent.customTemplates || [];
1017
+ const formattedCustom = customTemplates.map(template => ({
1018
+ ...template,
1019
+ type: 'custom'
1020
+ }));
1021
+
1022
+ return {
1023
+ builtInTemplates,
1024
+ customTemplates: formattedCustom,
1025
+ totalTemplates: builtInTemplates.length + formattedCustom.length,
1026
+ categories: [...new Set(builtInTemplates.map(t => t.category))]
1027
+ };
1028
+ }
1029
+
1030
+ /**
1031
+ * Apply a template to create structured tasks
1032
+ * @private
1033
+ */
1034
+ async applyTemplate(agent, templateId, projectContext = {}) {
1035
+ const template = this.taskTemplates[templateId] ||
1036
+ (agent.customTemplates || []).find(t => t.id === templateId);
1037
+
1038
+ if (!template) {
1039
+ throw new Error(`Template not found: ${templateId}`);
1040
+ }
1041
+
1042
+ const createdTasks = [];
1043
+ const taskMapping = new Map(); // Map template task titles to actual task IDs
1044
+
1045
+ // Apply project context to customize template
1046
+ const contextualizedTasks = this.applyProjectContext(template.tasks, projectContext);
1047
+
1048
+ // Create all tasks first
1049
+ for (const templateTask of contextualizedTasks) {
1050
+ const task = {
1051
+ id: `task-${uuidv4()}`,
1052
+ title: templateTask.title,
1053
+ description: templateTask.description,
1054
+ status: 'pending',
1055
+ priority: templateTask.priority,
1056
+ createdAt: new Date().toISOString(),
1057
+ updatedAt: new Date().toISOString(),
1058
+ templateId: templateId,
1059
+ templateOrigin: template.type || 'built-in',
1060
+ source: 'template-generated'
1061
+ };
1062
+
1063
+ agent.taskList.tasks.push(task);
1064
+ createdTasks.push(task);
1065
+ taskMapping.set(templateTask.title, task.id);
1066
+ }
1067
+
1068
+ // Create dependencies after all tasks exist
1069
+ for (let i = 0; i < contextualizedTasks.length; i++) {
1070
+ const templateTask = contextualizedTasks[i];
1071
+ const actualTask = createdTasks[i];
1072
+
1073
+ if (templateTask.dependencies && templateTask.dependencies.length > 0) {
1074
+ actualTask.dependencies = [];
1075
+
1076
+ for (const depTitle of templateTask.dependencies) {
1077
+ const depTaskId = taskMapping.get(depTitle);
1078
+ if (depTaskId) {
1079
+ actualTask.dependencies.push({
1080
+ taskId: depTaskId,
1081
+ type: 'blocks',
1082
+ createdAt: new Date().toISOString()
1083
+ });
1084
+
1085
+ // Set task as blocked if dependency isn't completed
1086
+ actualTask.status = 'blocked';
1087
+ }
1088
+ }
1089
+ }
1090
+ }
1091
+
1092
+ // Auto-prioritize the newly created tasks
1093
+ await this.autoPrioritizeAllTasks(agent);
1094
+
1095
+ return {
1096
+ template: {
1097
+ id: templateId,
1098
+ name: template.name,
1099
+ description: template.description
1100
+ },
1101
+ tasksCreated: createdTasks.length,
1102
+ tasks: createdTasks.map(task => ({
1103
+ id: task.id,
1104
+ title: task.title,
1105
+ priority: task.priority,
1106
+ status: task.status,
1107
+ dependencies: task.dependencies ? task.dependencies.length : 0
1108
+ })),
1109
+ workflowStructure: this.generateWorkflowVisualization(createdTasks)
1110
+ };
1111
+ }
1112
+
1113
+ /**
1114
+ * Apply project context to customize template tasks
1115
+ * @private
1116
+ */
1117
+ applyProjectContext(templateTasks, context) {
1118
+ return templateTasks.map(task => {
1119
+ let customizedTask = { ...task };
1120
+
1121
+ // Apply context-specific customizations
1122
+ if (context.projectName) {
1123
+ customizedTask.title = customizedTask.title.replace(/\[PROJECT\]/g, context.projectName);
1124
+ customizedTask.description = customizedTask.description.replace(/\[PROJECT\]/g, context.projectName);
1125
+ }
1126
+
1127
+ if (context.technology) {
1128
+ customizedTask.title = customizedTask.title.replace(/\[TECH\]/g, context.technology);
1129
+ customizedTask.description = customizedTask.description.replace(/\[TECH\]/g, context.technology);
1130
+ }
1131
+
1132
+ if (context.urgency === 'high') {
1133
+ customizedTask.priority = customizedTask.priority === 'low' ? 'medium' :
1134
+ customizedTask.priority === 'medium' ? 'high' : 'urgent';
1135
+ }
1136
+
1137
+ // Team size can affect priority rather than time estimates
1138
+ if (context.team === 'small' && customizedTask.priority === 'medium') {
1139
+ customizedTask.priority = 'high'; // Small teams need focused priorities
1140
+ }
1141
+
1142
+ return customizedTask;
1143
+ });
1144
+ }
1145
+
1146
+ /**
1147
+ * Create custom template from existing tasks or specification
1148
+ * @private
1149
+ */
1150
+ async createCustomTemplate(agent, customTemplate) {
1151
+ const { name, description, category, tasks } = customTemplate;
1152
+
1153
+ if (!name || !tasks || tasks.length === 0) {
1154
+ throw new Error('Custom template requires name and at least one task');
1155
+ }
1156
+
1157
+ const template = {
1158
+ id: `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
1159
+ name,
1160
+ description: description || `Custom template: ${name}`,
1161
+ category: category || 'custom',
1162
+ tasks: tasks.map(task => ({
1163
+ title: task.title,
1164
+ description: task.description || '',
1165
+ priority: task.priority || 'medium',
1166
+ dependencies: task.dependencies || []
1167
+ })),
1168
+ createdAt: new Date().toISOString(),
1169
+ type: 'custom'
1170
+ };
1171
+
1172
+ // Initialize custom templates array if not exists
1173
+ if (!agent.customTemplates) {
1174
+ agent.customTemplates = [];
1175
+ }
1176
+
1177
+ agent.customTemplates.push(template);
1178
+
1179
+ return {
1180
+ template: {
1181
+ id: template.id,
1182
+ name: template.name,
1183
+ description: template.description,
1184
+ category: template.category,
1185
+ taskCount: template.tasks.length
1186
+ },
1187
+ message: 'Custom template created successfully'
1188
+ };
1189
+ }
1190
+
1191
+ /**
1192
+ * Suggest templates based on existing tasks and patterns
1193
+ * @private
1194
+ */
1195
+ async suggestTemplates(agent) {
1196
+ const existingTasks = agent.taskList.tasks;
1197
+ const suggestions = [];
1198
+
1199
+ // Analyze existing task patterns
1200
+ const taskTitles = existingTasks.map(t => t.title.toLowerCase());
1201
+ const priorities = existingTasks.map(t => t.priority);
1202
+
1203
+ // Pattern-based suggestions
1204
+ if (taskTitles.some(title => title.includes('api') || title.includes('endpoint'))) {
1205
+ suggestions.push({
1206
+ templateId: 'api-integration',
1207
+ reason: 'Detected API-related tasks',
1208
+ confidence: 0.8
1209
+ });
1210
+ }
1211
+
1212
+ if (taskTitles.some(title => title.includes('bug') || title.includes('fix') || title.includes('error'))) {
1213
+ suggestions.push({
1214
+ templateId: 'bug-fix',
1215
+ reason: 'Detected bug fix tasks',
1216
+ confidence: 0.9
1217
+ });
1218
+ }
1219
+
1220
+ if (taskTitles.some(title => title.includes('feature') || title.includes('implement'))) {
1221
+ suggestions.push({
1222
+ templateId: 'feature-development',
1223
+ reason: 'Detected feature development tasks',
1224
+ confidence: 0.7
1225
+ });
1226
+ }
1227
+
1228
+ if (existingTasks.length >= 5 && priorities.includes('high') && priorities.includes('medium')) {
1229
+ suggestions.push({
1230
+ templateId: 'web-app-development',
1231
+ reason: 'Large project with mixed priorities suggests web app development',
1232
+ confidence: 0.6
1233
+ });
1234
+ }
1235
+
1236
+ // Enhance suggestions with template details
1237
+ const detailedSuggestions = suggestions.map(suggestion => {
1238
+ const template = this.taskTemplates[suggestion.templateId];
1239
+ return {
1240
+ ...suggestion,
1241
+ templateName: template.name,
1242
+ templateDescription: template.description,
1243
+ taskCount: template.tasks.length
1244
+ };
1245
+ });
1246
+
1247
+ return {
1248
+ suggestions: detailedSuggestions,
1249
+ analysisResults: {
1250
+ existingTaskCount: existingTasks.length,
1251
+ dominantPriority: this.getMostCommonPriority(priorities),
1252
+ detectedPatterns: suggestions.map(s => s.reason)
1253
+ }
1254
+ };
1255
+ }
1256
+
1257
+ /**
1258
+ * Generate workflow visualization for created tasks
1259
+ * @private
1260
+ */
1261
+ generateWorkflowVisualization(tasks) {
1262
+ const workflow = {
1263
+ phases: [],
1264
+ criticalPath: [],
1265
+ parallelTasks: []
1266
+ };
1267
+
1268
+ // Group tasks by their dependency level
1269
+ const levels = new Map();
1270
+ const processedTasks = new Set();
1271
+
1272
+ // Find root tasks (no dependencies)
1273
+ const rootTasks = tasks.filter(task => !task.dependencies || task.dependencies.length === 0);
1274
+ rootTasks.forEach(task => {
1275
+ levels.set(0, (levels.get(0) || []).concat([task]));
1276
+ processedTasks.add(task.id);
1277
+ });
1278
+
1279
+ // Build dependency levels
1280
+ let currentLevel = 0;
1281
+ while (processedTasks.size < tasks.length && currentLevel < 10) {
1282
+ currentLevel++;
1283
+ const currentLevelTasks = [];
1284
+
1285
+ for (const task of tasks) {
1286
+ if (processedTasks.has(task.id)) continue;
1287
+
1288
+ if (task.dependencies && task.dependencies.every(dep => processedTasks.has(dep.taskId))) {
1289
+ currentLevelTasks.push(task);
1290
+ processedTasks.add(task.id);
1291
+ }
1292
+ }
1293
+
1294
+ if (currentLevelTasks.length > 0) {
1295
+ levels.set(currentLevel, currentLevelTasks);
1296
+ }
1297
+ }
1298
+
1299
+ // Convert levels to phases
1300
+ for (const [level, levelTasks] of levels.entries()) {
1301
+ workflow.phases.push({
1302
+ phase: level + 1,
1303
+ tasks: levelTasks.map(task => ({
1304
+ id: task.id,
1305
+ title: task.title,
1306
+ priority: task.priority
1307
+ })),
1308
+ taskCount: levelTasks.length,
1309
+ canRunInParallel: levelTasks.length > 1
1310
+ });
1311
+ }
1312
+
1313
+ return workflow;
1314
+ }
1315
+
1316
+ /**
1317
+ * Get most common priority from array
1318
+ * @private
1319
+ */
1320
+ getMostCommonPriority(priorities) {
1321
+ if (priorities.length === 0) return 'medium';
1322
+
1323
+ const counts = priorities.reduce((acc, priority) => {
1324
+ acc[priority] = (acc[priority] || 0) + 1;
1325
+ return acc;
1326
+ }, {});
1327
+
1328
+ return Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b);
1329
+ }
1330
+
1331
+ /**
1332
+ * Progress tracking management (Phase 3.4)
1333
+ * @private
1334
+ */
1335
+ async trackProgress(agent, params) {
1336
+ const { mode = 'update', taskId, stage, milestone, note, percentage } = params;
1337
+
1338
+ let results = {};
1339
+
1340
+ if (mode === 'update' && taskId) {
1341
+ // Update progress for specific task
1342
+ results = await this.updateTaskProgress(agent, taskId, { stage, milestone, note, percentage });
1343
+ } else if (mode === 'overview') {
1344
+ // Get progress overview for all tasks
1345
+ results = await this.getProgressOverview(agent);
1346
+ } else if (mode === 'milestones' && taskId) {
1347
+ // Manage milestones for specific task
1348
+ results = await this.manageMilestones(agent, taskId, params);
1349
+ } else if (mode === 'calculate') {
1350
+ // Calculate progress based on subtasks and dependencies
1351
+ results = await this.calculateTaskProgress(agent, taskId);
1352
+ } else {
1353
+ throw new Error('Invalid progress mode. Use: update, overview, milestones, or calculate');
1354
+ }
1355
+
1356
+ return {
1357
+ message: `Progress tracking completed (${mode})`,
1358
+ mode,
1359
+ ...results
1360
+ };
1361
+ }
1362
+
1363
+ /**
1364
+ * Update progress for a specific task
1365
+ * @private
1366
+ */
1367
+ async updateTaskProgress(agent, taskId, progressData) {
1368
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
1369
+ if (!task) {
1370
+ throw new Error(`Task not found: ${taskId}`);
1371
+ }
1372
+
1373
+ // Initialize progress tracking if not exists
1374
+ if (!task.progress) {
1375
+ task.progress = {
1376
+ stage: 'not_started',
1377
+ percentage: 0,
1378
+ milestones: [],
1379
+ notes: [],
1380
+ stageHistory: []
1381
+ };
1382
+ }
1383
+
1384
+ const oldStage = task.progress.stage;
1385
+
1386
+ // Update stage if provided
1387
+ if (progressData.stage) {
1388
+ if (!this.progressStages.includes(progressData.stage)) {
1389
+ throw new Error(`Invalid progress stage: ${progressData.stage}. Must be: ${this.progressStages.join(', ')}`);
1390
+ }
1391
+
1392
+ task.progress.stage = progressData.stage;
1393
+
1394
+ // Track stage changes
1395
+ task.progress.stageHistory.push({
1396
+ from: oldStage,
1397
+ to: progressData.stage,
1398
+ timestamp: new Date().toISOString()
1399
+ });
1400
+
1401
+ // Auto-update task status based on stage
1402
+ if (progressData.stage === 'not_started' && task.status === 'in_progress') {
1403
+ task.status = 'pending';
1404
+ } else if (['planning', 'in_development', 'testing', 'review'].includes(progressData.stage) && task.status === 'pending') {
1405
+ task.status = 'in_progress';
1406
+ } else if (progressData.stage === 'completed' && task.status !== 'completed') {
1407
+ task.status = 'completed';
1408
+ task.completedAt = new Date().toISOString();
1409
+ }
1410
+ }
1411
+
1412
+ // Update percentage if provided
1413
+ if (progressData.percentage !== undefined) {
1414
+ const percent = Math.max(0, Math.min(100, parseInt(progressData.percentage)));
1415
+ task.progress.percentage = percent;
1416
+
1417
+ // Auto-update stage based on percentage
1418
+ if (percent === 0 && task.progress.stage !== 'not_started') {
1419
+ task.progress.stage = 'not_started';
1420
+ } else if (percent > 0 && percent < 25 && task.progress.stage === 'not_started') {
1421
+ task.progress.stage = 'planning';
1422
+ } else if (percent >= 25 && percent < 75 && ['not_started', 'planning'].includes(task.progress.stage)) {
1423
+ task.progress.stage = 'in_development';
1424
+ } else if (percent >= 75 && percent < 95 && task.progress.stage !== 'testing') {
1425
+ task.progress.stage = 'testing';
1426
+ } else if (percent >= 95 && percent < 100 && task.progress.stage !== 'review') {
1427
+ task.progress.stage = 'review';
1428
+ } else if (percent === 100) {
1429
+ task.progress.stage = 'completed';
1430
+ task.status = 'completed';
1431
+ task.completedAt = new Date().toISOString();
1432
+ }
1433
+ }
1434
+
1435
+ // Add milestone if provided
1436
+ if (progressData.milestone) {
1437
+ const milestone = {
1438
+ id: `milestone-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
1439
+ type: progressData.milestone.type || 'checkpoint',
1440
+ title: progressData.milestone.title || 'Progress Milestone',
1441
+ description: progressData.milestone.description || '',
1442
+ achievedAt: new Date().toISOString(),
1443
+ stage: task.progress.stage
1444
+ };
1445
+
1446
+ task.progress.milestones.push(milestone);
1447
+ }
1448
+
1449
+ // Add progress note if provided
1450
+ if (progressData.note) {
1451
+ task.progress.notes.push({
1452
+ id: `note-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
1453
+ content: progressData.note,
1454
+ timestamp: new Date().toISOString(),
1455
+ stage: task.progress.stage
1456
+ });
1457
+ }
1458
+
1459
+ task.updatedAt = new Date().toISOString();
1460
+
1461
+ // Calculate progress for parent task if this is a subtask
1462
+ if (task.parentTaskId) {
1463
+ await this.calculateTaskProgress(agent, task.parentTaskId);
1464
+ }
1465
+
1466
+ return {
1467
+ task: {
1468
+ id: task.id,
1469
+ title: task.title,
1470
+ status: task.status,
1471
+ progress: task.progress
1472
+ },
1473
+ changes: {
1474
+ stageChanged: oldStage !== task.progress.stage,
1475
+ oldStage,
1476
+ newStage: task.progress.stage,
1477
+ milestoneAdded: !!progressData.milestone,
1478
+ noteAdded: !!progressData.note
1479
+ }
1480
+ };
1481
+ }
1482
+
1483
+ /**
1484
+ * Get progress overview for all tasks
1485
+ * @private
1486
+ */
1487
+ async getProgressOverview(agent) {
1488
+ const tasks = agent.taskList.tasks;
1489
+ const taskProgress = tasks.map(task => {
1490
+ const progress = task.progress || { stage: 'not_started', percentage: 0, milestones: [], notes: [] };
1491
+
1492
+ return {
1493
+ id: task.id,
1494
+ title: task.title,
1495
+ status: task.status,
1496
+ priority: task.priority,
1497
+ stage: progress.stage,
1498
+ percentage: progress.percentage,
1499
+ milestoneCount: progress.milestones ? progress.milestones.length : 0,
1500
+ isBlocked: task.status === 'blocked',
1501
+ hasSubtasks: !!(task.subtasks && task.subtasks.length > 0),
1502
+ parentTaskId: task.parentTaskId
1503
+ };
1504
+ });
1505
+
1506
+ // Calculate overall statistics
1507
+ const stats = {
1508
+ totalTasks: tasks.length,
1509
+ byStage: {},
1510
+ byStatus: {},
1511
+ averageProgress: 0,
1512
+ blockedTasks: 0,
1513
+ completedTasks: 0
1514
+ };
1515
+
1516
+ this.progressStages.forEach(stage => {
1517
+ stats.byStage[stage] = taskProgress.filter(t => t.stage === stage).length;
1518
+ });
1519
+
1520
+ this.taskStatuses.forEach(status => {
1521
+ stats.byStatus[status] = taskProgress.filter(t => t.status === status).length;
1522
+ });
1523
+
1524
+ stats.averageProgress = tasks.length > 0 ?
1525
+ Math.round(taskProgress.reduce((sum, t) => sum + t.percentage, 0) / tasks.length) : 0;
1526
+
1527
+ stats.blockedTasks = stats.byStatus.blocked || 0;
1528
+ stats.completedTasks = stats.byStatus.completed || 0;
1529
+
1530
+ // Find critical path and bottlenecks
1531
+ const criticalTasks = taskProgress.filter(t =>
1532
+ t.priority === 'urgent' && t.status !== 'completed'
1533
+ );
1534
+
1535
+ const bottlenecks = taskProgress.filter(t =>
1536
+ t.isBlocked && this.findTasksBlockedBy(t.id, tasks).length > 0
1537
+ );
1538
+
1539
+ return {
1540
+ overview: stats,
1541
+ tasks: taskProgress,
1542
+ criticalTasks,
1543
+ bottlenecks: bottlenecks.map(t => ({
1544
+ taskId: t.id,
1545
+ title: t.title,
1546
+ blockedTasksCount: this.findTasksBlockedBy(t.id, tasks).length
1547
+ })),
1548
+ recommendations: this.generateProgressRecommendations(taskProgress, stats)
1549
+ };
1550
+ }
1551
+
1552
+ /**
1553
+ * Calculate task progress based on subtasks and dependencies
1554
+ * @private
1555
+ */
1556
+ async calculateTaskProgress(agent, taskId) {
1557
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
1558
+ if (!task) {
1559
+ throw new Error(`Task not found: ${taskId}`);
1560
+ }
1561
+
1562
+ // Initialize progress if not exists
1563
+ if (!task.progress) {
1564
+ task.progress = {
1565
+ stage: 'not_started',
1566
+ percentage: 0,
1567
+ milestones: [],
1568
+ notes: [],
1569
+ stageHistory: []
1570
+ };
1571
+ }
1572
+
1573
+ let calculatedPercentage = 0;
1574
+ let calculationMethod = 'manual';
1575
+
1576
+ // Calculate based on subtasks if they exist
1577
+ if (task.subtasks && task.subtasks.length > 0) {
1578
+ const subtasks = task.subtasks.map(subtaskId =>
1579
+ agent.taskList.tasks.find(t => t.id === subtaskId)
1580
+ ).filter(Boolean);
1581
+
1582
+ if (subtasks.length > 0) {
1583
+ const subtaskProgress = subtasks.map(subtask => {
1584
+ if (subtask.status === 'completed') return 100;
1585
+ if (subtask.progress && subtask.progress.percentage !== undefined) {
1586
+ return subtask.progress.percentage;
1587
+ }
1588
+ return subtask.status === 'in_progress' ? 25 : 0;
1589
+ });
1590
+
1591
+ calculatedPercentage = Math.round(
1592
+ subtaskProgress.reduce((sum, p) => sum + p, 0) / subtasks.length
1593
+ );
1594
+ calculationMethod = 'subtasks';
1595
+ }
1596
+ }
1597
+
1598
+ // If no subtasks, calculate based on dependencies completion
1599
+ else if (task.dependencies && task.dependencies.length > 0) {
1600
+ const completedDeps = task.dependencies.filter(dep => {
1601
+ const depTask = agent.taskList.tasks.find(t => t.id === dep.taskId);
1602
+ return depTask && depTask.status === 'completed';
1603
+ }).length;
1604
+
1605
+ const depProgress = (completedDeps / task.dependencies.length) * 30; // Dependencies contribute 30%
1606
+ const ownProgress = task.status === 'completed' ? 70 :
1607
+ task.status === 'in_progress' ? 35 : 0; // Own progress contributes 70%
1608
+
1609
+ calculatedPercentage = Math.round(depProgress + ownProgress);
1610
+ calculationMethod = 'dependencies';
1611
+ }
1612
+
1613
+ // Fallback to status-based calculation
1614
+ else {
1615
+ if (task.status === 'completed') calculatedPercentage = 100;
1616
+ else if (task.status === 'in_progress') calculatedPercentage = task.progress.percentage || 50;
1617
+ else if (task.status === 'pending') calculatedPercentage = 0;
1618
+ else if (task.status === 'blocked') calculatedPercentage = task.progress.percentage || 0;
1619
+
1620
+ calculationMethod = 'status';
1621
+ }
1622
+
1623
+ // Update the task's calculated progress
1624
+ task.progress.calculatedPercentage = calculatedPercentage;
1625
+ task.progress.calculationMethod = calculationMethod;
1626
+ task.progress.lastCalculated = new Date().toISOString();
1627
+
1628
+ // Auto-update stage based on calculated percentage if no manual stage set recently
1629
+ const recentStageUpdate = task.progress.stageHistory.length > 0 &&
1630
+ (Date.now() - new Date(task.progress.stageHistory[task.progress.stageHistory.length - 1].timestamp).getTime()) < 300000; // 5 minutes
1631
+
1632
+ if (!recentStageUpdate) {
1633
+ const autoStage = this.getStageFromPercentage(calculatedPercentage);
1634
+ if (autoStage !== task.progress.stage) {
1635
+ task.progress.stage = autoStage;
1636
+ task.progress.stageHistory.push({
1637
+ from: task.progress.stage,
1638
+ to: autoStage,
1639
+ timestamp: new Date().toISOString(),
1640
+ automatic: true
1641
+ });
1642
+ }
1643
+ }
1644
+
1645
+ task.updatedAt = new Date().toISOString();
1646
+
1647
+ return {
1648
+ taskId: task.id,
1649
+ title: task.title,
1650
+ calculatedPercentage,
1651
+ calculationMethod,
1652
+ manualPercentage: task.progress.percentage,
1653
+ stage: task.progress.stage,
1654
+ subtaskCount: task.subtasks ? task.subtasks.length : 0,
1655
+ dependencyCount: task.dependencies ? task.dependencies.length : 0
1656
+ };
1657
+ }
1658
+
1659
+ /**
1660
+ * Generate progress recommendations
1661
+ * @private
1662
+ */
1663
+ generateProgressRecommendations(taskProgress, stats) {
1664
+ const recommendations = [];
1665
+
1666
+ // Blocked task recommendations
1667
+ if (stats.blockedTasks > 0) {
1668
+ recommendations.push({
1669
+ type: 'urgent',
1670
+ category: 'blocked_tasks',
1671
+ message: `${stats.blockedTasks} tasks are blocked. Review dependencies to unblock progress.`,
1672
+ actionable: true
1673
+ });
1674
+ }
1675
+
1676
+ // Stalled task recommendations
1677
+ const stalledTasks = taskProgress.filter(t =>
1678
+ t.status === 'in_progress' && t.percentage < 25
1679
+ );
1680
+
1681
+ if (stalledTasks.length > 0) {
1682
+ recommendations.push({
1683
+ type: 'warning',
1684
+ category: 'stalled_progress',
1685
+ message: `${stalledTasks.length} tasks are in progress but showing low progress. Consider breaking them into smaller subtasks.`,
1686
+ actionable: true
1687
+ });
1688
+ }
1689
+
1690
+ // High progress tasks ready for completion
1691
+ const nearCompletionTasks = taskProgress.filter(t =>
1692
+ t.percentage >= 90 && t.status !== 'completed'
1693
+ );
1694
+
1695
+ if (nearCompletionTasks.length > 0) {
1696
+ recommendations.push({
1697
+ type: 'success',
1698
+ category: 'near_completion',
1699
+ message: `${nearCompletionTasks.length} tasks are near completion. Focus on finishing these for quick wins.`,
1700
+ actionable: true
1701
+ });
1702
+ }
1703
+
1704
+ // Overall progress recommendations
1705
+ if (stats.averageProgress < 25) {
1706
+ recommendations.push({
1707
+ type: 'info',
1708
+ category: 'overall_progress',
1709
+ message: 'Overall progress is low. Consider prioritizing and focusing on fewer tasks.',
1710
+ actionable: false
1711
+ });
1712
+ }
1713
+
1714
+ return recommendations;
1715
+ }
1716
+
1717
+ /**
1718
+ * Get stage from percentage
1719
+ * @private
1720
+ */
1721
+ getStageFromPercentage(percentage) {
1722
+ if (percentage === 0) return 'not_started';
1723
+ if (percentage < 25) return 'planning';
1724
+ if (percentage < 75) return 'in_development';
1725
+ if (percentage < 95) return 'testing';
1726
+ if (percentage < 100) return 'review';
1727
+ return 'completed';
1728
+ }
1729
+
1730
+ /**
1731
+ * Set scheduler reference for dependency management (Phase 3)
1732
+ * @param {Object} scheduler - AgentScheduler instance
1733
+ */
1734
+ setScheduler(scheduler) {
1735
+ this.scheduler = scheduler;
1736
+ this.logger?.info('TaskManagerTool: Scheduler dependency injected');
1737
+ }
1738
+
1739
+ /**
1740
+ * Intelligent task prioritization (Phase 3.2)
1741
+ * @private
1742
+ */
1743
+ async intelligentPrioritization(agent, params) {
1744
+ const { mode = 'auto', taskId } = params;
1745
+
1746
+ let results = {};
1747
+
1748
+ if (mode === 'auto') {
1749
+ // Auto-prioritize all tasks
1750
+ results = await this.autoPrioritizeAllTasks(agent);
1751
+ } else if (mode === 'analyze' && taskId) {
1752
+ // Analyze specific task priority
1753
+ results = await this.analyzeTaskPriority(agent, taskId);
1754
+ } else if (mode === 'balance') {
1755
+ // Balance priorities across all agents
1756
+ results = await this.balanceCrossAgentPriorities(agent);
1757
+ } else {
1758
+ throw new Error('Invalid prioritization mode. Use: auto, analyze, or balance');
1759
+ }
1760
+
1761
+ return {
1762
+ message: `Intelligent prioritization completed (${mode})`,
1763
+ mode,
1764
+ ...results
1765
+ };
1766
+ }
1767
+
1768
+ /**
1769
+ * Auto-prioritize all tasks using intelligent scoring
1770
+ * @private
1771
+ */
1772
+ async autoPrioritizeAllTasks(agent) {
1773
+ const tasks = agent.taskList.tasks.filter(t =>
1774
+ t.status === 'pending' || t.status === 'in_progress'
1775
+ );
1776
+
1777
+ if (tasks.length === 0) {
1778
+ return { message: 'No active tasks to prioritize' };
1779
+ }
1780
+
1781
+ // Calculate priority scores for all tasks
1782
+ const tasksWithScores = tasks.map(task => ({
1783
+ ...task,
1784
+ priorityScore: this.calculatePriorityScore(task, agent.taskList.tasks),
1785
+ originalPriority: task.priority
1786
+ }));
1787
+
1788
+ // Sort by priority score (higher = more important)
1789
+ tasksWithScores.sort((a, b) => b.priorityScore - a.priorityScore);
1790
+
1791
+ // Assign new priorities based on scores
1792
+ const priorityMapping = ['urgent', 'high', 'medium', 'low'];
1793
+ const updatedTasks = [];
1794
+
1795
+ tasksWithScores.forEach((task, index) => {
1796
+ const newPriorityIndex = Math.min(
1797
+ Math.floor(index / Math.max(1, tasks.length / 4)),
1798
+ priorityMapping.length - 1
1799
+ );
1800
+ const newPriority = priorityMapping[newPriorityIndex];
1801
+
1802
+ if (task.originalPriority !== newPriority) {
1803
+ const originalTask = agent.taskList.tasks.find(t => t.id === task.id);
1804
+ originalTask.priority = newPriority;
1805
+ originalTask.updatedAt = new Date().toISOString();
1806
+ originalTask.priorityScore = task.priorityScore;
1807
+ originalTask.priorityReason = this.generatePriorityReason(task);
1808
+
1809
+ updatedTasks.push({
1810
+ id: task.id,
1811
+ title: task.title,
1812
+ oldPriority: task.originalPriority,
1813
+ newPriority: newPriority,
1814
+ score: task.priorityScore.toFixed(2),
1815
+ reason: originalTask.priorityReason
1816
+ });
1817
+ }
1818
+ });
1819
+
1820
+ return {
1821
+ totalTasks: tasks.length,
1822
+ updatedTasks: updatedTasks.length,
1823
+ changes: updatedTasks
1824
+ };
1825
+ }
1826
+
1827
+ /**
1828
+ * Calculate intelligent priority score for a task
1829
+ * @private
1830
+ */
1831
+ calculatePriorityScore(task, allTasks) {
1832
+ let score = 0;
1833
+
1834
+ // Base user priority score
1835
+ const priorityScores = { urgent: 4, high: 3, medium: 2, low: 1 };
1836
+ score += priorityScores[task.priority] * this.priorityWeights.userPriority;
1837
+
1838
+ // Age factor (older tasks get higher priority)
1839
+ const ageHours = (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60);
1840
+ score += Math.min(ageHours / 24, 3) * this.priorityWeights.age;
1841
+
1842
+ // Blocking factor (tasks that block others get higher priority)
1843
+ const blockedTasks = this.findTasksBlockedBy(task.id, allTasks);
1844
+ score += blockedTasks.length * this.priorityWeights.blocking;
1845
+
1846
+ // Dependency complexity factor
1847
+ const dependencyCount = (task.dependencies || []).length;
1848
+ score += Math.min(dependencyCount, 3) * this.priorityWeights.dependency;
1849
+
1850
+ // Subtask factor (parent tasks with many subtasks get higher priority)
1851
+ const subtaskCount = (task.subtasks || []).length;
1852
+ score += Math.min(subtaskCount, 2) * this.priorityWeights.dependency;
1853
+
1854
+ return score;
1855
+ }
1856
+
1857
+ /**
1858
+ * Find tasks that are blocked by the given task
1859
+ * @private
1860
+ */
1861
+ findTasksBlockedBy(taskId, allTasks) {
1862
+ return allTasks.filter(task => {
1863
+ if (!task.dependencies) return false;
1864
+ return task.dependencies.some(dep =>
1865
+ dep.taskId === taskId && dep.type === 'blocks'
1866
+ );
1867
+ });
1868
+ }
1869
+
1870
+ /**
1871
+ * Generate human-readable priority reason
1872
+ * @private
1873
+ */
1874
+ generatePriorityReason(task) {
1875
+ const reasons = [];
1876
+
1877
+ if (task.priorityScore > 8) {
1878
+ reasons.push('high overall impact');
1879
+ }
1880
+
1881
+ const ageHours = (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60);
1882
+ if (ageHours > 24) {
1883
+ reasons.push('overdue task');
1884
+ }
1885
+
1886
+ if (task.priority === 'urgent') {
1887
+ reasons.push('user-marked urgent');
1888
+ }
1889
+
1890
+ if ((task.subtasks || []).length > 0) {
1891
+ reasons.push('has subtasks');
1892
+ }
1893
+
1894
+ return reasons.length > 0 ? reasons.join(', ') : 'standard prioritization';
1895
+ }
1896
+
1897
+ /**
1898
+ * Analyze priority of a specific task
1899
+ * @private
1900
+ */
1901
+ async analyzeTaskPriority(agent, taskId) {
1902
+ const task = agent.taskList.tasks.find(t => t.id === taskId);
1903
+ if (!task) {
1904
+ throw new Error(`Task not found: ${taskId}`);
1905
+ }
1906
+
1907
+ const score = this.calculatePriorityScore(task, agent.taskList.tasks);
1908
+ const blockedTasks = this.findTasksBlockedBy(taskId, agent.taskList.tasks);
1909
+ const reason = this.generatePriorityReason({ ...task, priorityScore: score });
1910
+
1911
+ return {
1912
+ task: {
1913
+ id: task.id,
1914
+ title: task.title,
1915
+ currentPriority: task.priority,
1916
+ priorityScore: score.toFixed(2),
1917
+ reason
1918
+ },
1919
+ analysis: {
1920
+ blocksOtherTasks: blockedTasks.length,
1921
+ ageInHours: ((Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60)).toFixed(1),
1922
+ dependencyCount: (task.dependencies || []).length,
1923
+ subtaskCount: (task.subtasks || []).length
1924
+ },
1925
+ blockedTasks: blockedTasks.map(t => ({ id: t.id, title: t.title }))
1926
+ };
1927
+ }
1928
+
1929
+ /**
1930
+ * Balance priorities across all agents (requires scheduler)
1931
+ * @private
1932
+ */
1933
+ async balanceCrossAgentPriorities(agent) {
1934
+ if (!this.scheduler || typeof this.scheduler.getAllAgents !== 'function') {
1935
+ return { message: 'Cross-agent balancing requires scheduler integration' };
1936
+ }
1937
+
1938
+ try {
1939
+ const allAgents = await this.scheduler.getAllAgents();
1940
+ const agentWorkloads = [];
1941
+
1942
+ allAgents.forEach(ag => {
1943
+ if (ag.taskList && ag.taskList.tasks) {
1944
+ const activeTasks = ag.taskList.tasks.filter(t =>
1945
+ t.status === 'pending' || t.status === 'in_progress'
1946
+ );
1947
+ const urgentTasks = activeTasks.filter(t => t.priority === 'urgent').length;
1948
+ const highTasks = activeTasks.filter(t => t.priority === 'high').length;
1949
+
1950
+ agentWorkloads.push({
1951
+ agentId: ag.id,
1952
+ agentName: ag.name,
1953
+ totalActive: activeTasks.length,
1954
+ urgent: urgentTasks,
1955
+ high: highTasks,
1956
+ workloadScore: urgentTasks * 3 + highTasks * 2 + activeTasks.length
1957
+ });
1958
+ }
1959
+ });
1960
+
1961
+ // Sort by workload (lowest first)
1962
+ agentWorkloads.sort((a, b) => a.workloadScore - b.workloadScore);
1963
+
1964
+ return {
1965
+ currentAgent: {
1966
+ agentId: agent.id,
1967
+ rank: agentWorkloads.findIndex(a => a.agentId === agent.id) + 1,
1968
+ totalAgents: agentWorkloads.length
1969
+ },
1970
+ workloadDistribution: agentWorkloads,
1971
+ recommendation: this.generateBalancingRecommendation(agent, agentWorkloads)
1972
+ };
1973
+ } catch (error) {
1974
+ return {
1975
+ error: `Cross-agent balancing failed: ${error.message}`,
1976
+ fallback: 'Using single-agent prioritization'
1977
+ };
1978
+ }
1979
+ }
1980
+
1981
+ /**
1982
+ * Generate workload balancing recommendation
1983
+ * @private
1984
+ */
1985
+ generateBalancingRecommendation(currentAgent, workloads) {
1986
+ const current = workloads.find(w => w.agentId === currentAgent.id);
1987
+ if (!current) return 'No recommendation available';
1988
+
1989
+ const avgWorkload = workloads.reduce((sum, w) => sum + w.workloadScore, 0) / workloads.length;
1990
+
1991
+ if (current.workloadScore > avgWorkload * 1.5) {
1992
+ return 'Consider delegating some tasks to less busy agents';
1993
+ } else if (current.workloadScore < avgWorkload * 0.5) {
1994
+ return 'Agent has capacity for additional high-priority tasks';
1995
+ } else {
1996
+ return 'Workload is well balanced';
1997
+ }
1998
+ }
1999
+
2000
+ /**
2001
+ * Generate task summary
2002
+ * @private
2003
+ */
2004
+ generateTaskSummary(taskList) {
2005
+ const tasks = taskList.tasks;
2006
+ const pending = tasks.filter(t => t.status === 'pending').length;
2007
+ const inProgress = tasks.filter(t => t.status === 'in_progress').length;
2008
+ const completed = tasks.filter(t => t.status === 'completed').length;
2009
+ const cancelled = tasks.filter(t => t.status === 'cancelled').length;
2010
+
2011
+ const parts = [];
2012
+ if (pending > 0) parts.push(`${pending} pending`);
2013
+ if (inProgress > 0) parts.push(`${inProgress} in-progress`);
2014
+ if (completed > 0) parts.push(`${completed} completed`);
2015
+ if (cancelled > 0) parts.push(`${cancelled} cancelled`);
2016
+
2017
+ return `Tasks: ${tasks.length} total (${parts.join(', ') || 'none'})`;
2018
+ }
2019
+
2020
+ /**
2021
+ * Phase 3.5: Generate task analytics and reporting
2022
+ * @private
2023
+ */
2024
+ async generateAnalytics(agent, params) {
2025
+ const { mode = 'summary', timeframe = '30', reportType = 'comprehensive', agentId } = params;
2026
+
2027
+ let results = {};
2028
+
2029
+ switch (mode) {
2030
+ case 'summary':
2031
+ results = await this.getAnalyticsSummary(agent, timeframe);
2032
+ break;
2033
+ case 'performance':
2034
+ results = await this.getPerformanceMetrics(agent, timeframe);
2035
+ break;
2036
+ case 'trends':
2037
+ results = await this.getTrendAnalysis(agent, timeframe);
2038
+ break;
2039
+ case 'team':
2040
+ results = await this.getTeamAnalytics(timeframe);
2041
+ break;
2042
+ case 'export':
2043
+ results = await this.exportAnalytics(agent, params);
2044
+ break;
2045
+ case 'insights':
2046
+ results = await this.generateInsights(agent, timeframe);
2047
+ break;
2048
+ default:
2049
+ throw new Error('Invalid analytics mode. Use: summary, performance, trends, team, export, or insights');
2050
+ }
2051
+
2052
+ return {
2053
+ message: `Analytics report generated (${mode})`,
2054
+ mode,
2055
+ timeframe,
2056
+ generatedAt: new Date().toISOString(),
2057
+ ...results
2058
+ };
2059
+ }
2060
+
2061
+ /**
2062
+ * Get comprehensive analytics summary
2063
+ * @private
2064
+ */
2065
+ async getAnalyticsSummary(agent, timeframe) {
2066
+ const tasks = agent.taskList.tasks;
2067
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2068
+
2069
+ // Filter tasks within timeframe
2070
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2071
+
2072
+ const summary = {
2073
+ overview: {
2074
+ totalTasks: timeframeTasks.length,
2075
+ completed: timeframeTasks.filter(t => t.status === 'completed').length,
2076
+ inProgress: timeframeTasks.filter(t => t.status === 'in_progress').length,
2077
+ pending: timeframeTasks.filter(t => t.status === 'pending').length,
2078
+ cancelled: timeframeTasks.filter(t => t.status === 'cancelled').length,
2079
+ blocked: timeframeTasks.filter(t => t.status === 'blocked').length
2080
+ },
2081
+ priorityBreakdown: {
2082
+ urgent: timeframeTasks.filter(t => t.priority === 'urgent').length,
2083
+ high: timeframeTasks.filter(t => t.priority === 'high').length,
2084
+ medium: timeframeTasks.filter(t => t.priority === 'medium').length,
2085
+ low: timeframeTasks.filter(t => t.priority === 'low').length
2086
+ },
2087
+ progressMetrics: this.calculateProgressMetrics(timeframeTasks),
2088
+ dependencyMetrics: this.calculateDependencyMetrics(timeframeTasks),
2089
+ templateUsage: this.calculateTemplateUsage(timeframeTasks)
2090
+ };
2091
+
2092
+ // Calculate completion rate
2093
+ summary.completionRate = summary.overview.totalTasks > 0
2094
+ ? Math.round((summary.overview.completed / summary.overview.totalTasks) * 100)
2095
+ : 0;
2096
+
2097
+ // Calculate average task age
2098
+ const activeTasks = timeframeTasks.filter(t => t.status !== 'completed' && t.status !== 'cancelled');
2099
+ summary.averageTaskAge = activeTasks.length > 0
2100
+ ? Math.round(activeTasks.reduce((sum, task) => {
2101
+ return sum + (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60 * 24);
2102
+ }, 0) / activeTasks.length)
2103
+ : 0;
2104
+
2105
+ return {
2106
+ summary,
2107
+ insights: this.generateSummaryInsights(summary)
2108
+ };
2109
+ }
2110
+
2111
+ /**
2112
+ * Get performance metrics
2113
+ * @private
2114
+ */
2115
+ async getPerformanceMetrics(agent, timeframe) {
2116
+ const tasks = agent.taskList.tasks;
2117
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2118
+ const completedTasks = tasks.filter(t =>
2119
+ t.status === 'completed' &&
2120
+ t.completedAt &&
2121
+ new Date(t.completedAt) >= cutoffDate
2122
+ );
2123
+
2124
+ const metrics = {
2125
+ productivity: {
2126
+ tasksCompleted: completedTasks.length,
2127
+ completionRate: this.calculateCompletionRate(tasks, timeframe),
2128
+ averageCompletionTime: this.calculateAverageCompletionTime(completedTasks),
2129
+ velocityTrend: this.calculateVelocityTrend(tasks, timeframe)
2130
+ },
2131
+ quality: {
2132
+ blockedTasksRate: this.calculateBlockedTasksRate(tasks),
2133
+ cancelledTasksRate: this.calculateCancelledTasksRate(tasks, timeframe),
2134
+ reworkRate: this.calculateReworkRate(tasks, timeframe)
2135
+ },
2136
+ efficiency: {
2137
+ priorityAccuracy: this.calculatePriorityAccuracy(completedTasks),
2138
+ dependencyHandling: this.calculateDependencyEfficiency(tasks),
2139
+ progressConsistency: this.calculateProgressConsistency(tasks)
2140
+ }
2141
+ };
2142
+
2143
+ return {
2144
+ metrics,
2145
+ recommendations: this.generatePerformanceRecommendations(metrics)
2146
+ };
2147
+ }
2148
+
2149
+ /**
2150
+ * Get trend analysis
2151
+ * @private
2152
+ */
2153
+ async getTrendAnalysis(agent, timeframe) {
2154
+ const tasks = agent.taskList.tasks;
2155
+ const days = parseInt(timeframe);
2156
+ const trends = {
2157
+ daily: this.calculateDailyTrends(tasks, days),
2158
+ weekly: this.calculateWeeklyTrends(tasks, days),
2159
+ priorityTrends: this.calculatePriorityTrends(tasks, days),
2160
+ progressTrends: this.calculateProgressTrends(tasks, days)
2161
+ };
2162
+
2163
+ return {
2164
+ trends,
2165
+ forecasts: this.generateForecasts(trends),
2166
+ patterns: this.identifyPatterns(trends)
2167
+ };
2168
+ }
2169
+
2170
+ /**
2171
+ * Get team-wide analytics (across all agents)
2172
+ * @private
2173
+ */
2174
+ async getTeamAnalytics(timeframe) {
2175
+ if (!this.scheduler || !this.scheduler.getAllAgents) {
2176
+ throw new Error('Team analytics requires scheduler with getAllAgents method');
2177
+ }
2178
+
2179
+ const allAgents = await this.scheduler.getAllAgents();
2180
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2181
+
2182
+ const teamData = {
2183
+ agents: [],
2184
+ aggregatedMetrics: {
2185
+ totalTasks: 0,
2186
+ totalCompleted: 0,
2187
+ averageWorkload: 0,
2188
+ topPerformers: [],
2189
+ bottlenecks: []
2190
+ }
2191
+ };
2192
+
2193
+ // Analyze each agent
2194
+ for (const agent of allAgents) {
2195
+ if (!agent.taskList || !agent.taskList.tasks) continue;
2196
+
2197
+ const tasks = agent.taskList.tasks;
2198
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2199
+
2200
+ const agentMetrics = {
2201
+ agentId: agent.id,
2202
+ agentName: agent.name,
2203
+ totalTasks: timeframeTasks.length,
2204
+ completed: timeframeTasks.filter(t => t.status === 'completed').length,
2205
+ pending: timeframeTasks.filter(t => t.status === 'pending').length,
2206
+ inProgress: timeframeTasks.filter(t => t.status === 'in_progress').length,
2207
+ workloadScore: this.calculateWorkloadScore(tasks),
2208
+ completionRate: timeframeTasks.length > 0
2209
+ ? Math.round((timeframeTasks.filter(t => t.status === 'completed').length / timeframeTasks.length) * 100)
2210
+ : 0
2211
+ };
2212
+
2213
+ teamData.agents.push(agentMetrics);
2214
+ teamData.aggregatedMetrics.totalTasks += agentMetrics.totalTasks;
2215
+ teamData.aggregatedMetrics.totalCompleted += agentMetrics.completed;
2216
+ }
2217
+
2218
+ // Calculate team-level metrics
2219
+ teamData.aggregatedMetrics.teamCompletionRate = teamData.aggregatedMetrics.totalTasks > 0
2220
+ ? Math.round((teamData.aggregatedMetrics.totalCompleted / teamData.aggregatedMetrics.totalTasks) * 100)
2221
+ : 0;
2222
+
2223
+ teamData.aggregatedMetrics.averageWorkload = teamData.agents.length > 0
2224
+ ? Math.round(teamData.agents.reduce((sum, a) => sum + a.workloadScore, 0) / teamData.agents.length)
2225
+ : 0;
2226
+
2227
+ // Identify top performers and bottlenecks
2228
+ teamData.aggregatedMetrics.topPerformers = teamData.agents
2229
+ .filter(a => a.completionRate >= 80)
2230
+ .sort((a, b) => b.completionRate - a.completionRate)
2231
+ .slice(0, 3);
2232
+
2233
+ teamData.aggregatedMetrics.bottlenecks = teamData.agents
2234
+ .filter(a => a.workloadScore > teamData.aggregatedMetrics.averageWorkload * 1.5)
2235
+ .sort((a, b) => b.workloadScore - a.workloadScore);
2236
+
2237
+ return {
2238
+ teamAnalytics: teamData,
2239
+ workloadDistribution: this.analyzeWorkloadDistribution(teamData.agents),
2240
+ collaborationMetrics: this.analyzeCollaborationMetrics(allAgents)
2241
+ };
2242
+ }
2243
+
2244
+ /**
2245
+ * Export analytics data
2246
+ * @private
2247
+ */
2248
+ async exportAnalytics(agent, params) {
2249
+ const { format = 'json', includeRawData = false, timeframe = '30' } = params;
2250
+
2251
+ const analyticsData = {
2252
+ metadata: {
2253
+ agentId: agent.id,
2254
+ agentName: agent.name,
2255
+ exportedAt: new Date().toISOString(),
2256
+ timeframe: `${timeframe} days`,
2257
+ format
2258
+ },
2259
+ summary: await this.getAnalyticsSummary(agent, timeframe),
2260
+ performance: await this.getPerformanceMetrics(agent, timeframe),
2261
+ trends: await this.getTrendAnalysis(agent, timeframe)
2262
+ };
2263
+
2264
+ if (includeRawData) {
2265
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2266
+ analyticsData.rawData = {
2267
+ tasks: agent.taskList.tasks.filter(t => new Date(t.createdAt) >= cutoffDate)
2268
+ };
2269
+ }
2270
+
2271
+ let exportedData;
2272
+ switch (format.toLowerCase()) {
2273
+ case 'json':
2274
+ exportedData = JSON.stringify(analyticsData, null, 2);
2275
+ break;
2276
+ case 'csv':
2277
+ exportedData = this.convertToCSV(analyticsData);
2278
+ break;
2279
+ case 'summary':
2280
+ exportedData = this.generateTextSummary(analyticsData);
2281
+ break;
2282
+ default:
2283
+ throw new Error('Invalid export format. Use: json, csv, or summary');
2284
+ }
2285
+
2286
+ return {
2287
+ exportData: exportedData,
2288
+ format,
2289
+ size: exportedData.length,
2290
+ records: analyticsData.rawData ? analyticsData.rawData.tasks.length : 0
2291
+ };
2292
+ }
2293
+
2294
+ /**
2295
+ * Generate actionable insights
2296
+ * @private
2297
+ */
2298
+ async generateInsights(agent, timeframe) {
2299
+ const summary = await this.getAnalyticsSummary(agent, timeframe);
2300
+ const performance = await this.getPerformanceMetrics(agent, timeframe);
2301
+ const trends = await this.getTrendAnalysis(agent, timeframe);
2302
+
2303
+ const insights = {
2304
+ productivity: this.generateProductivityInsights(summary, performance, trends),
2305
+ workflow: this.generateWorkflowInsights(summary, performance, trends),
2306
+ optimization: this.generateOptimizationInsights(summary, performance, trends),
2307
+ predictions: this.generatePredictions(trends)
2308
+ };
2309
+
2310
+ return {
2311
+ insights,
2312
+ actionItems: this.generateActionItems(insights),
2313
+ priorities: this.generatePriorityRecommendations(insights)
2314
+ };
2315
+ }
2316
+
2317
+ // Helper methods for analytics calculations
2318
+
2319
+ calculateProgressMetrics(tasks) {
2320
+ const tasksWithProgress = tasks.filter(t => t.progress);
2321
+ if (tasksWithProgress.length === 0) return { averageProgress: 0, stageDistribution: {} };
2322
+
2323
+ const averageProgress = Math.round(
2324
+ tasksWithProgress.reduce((sum, t) => sum + (t.progress.percentage || 0), 0) / tasksWithProgress.length
2325
+ );
2326
+
2327
+ const stageDistribution = {};
2328
+ this.progressStages.forEach(stage => {
2329
+ stageDistribution[stage] = tasksWithProgress.filter(t => t.progress.stage === stage).length;
2330
+ });
2331
+
2332
+ return { averageProgress, stageDistribution };
2333
+ }
2334
+
2335
+ calculateDependencyMetrics(tasks) {
2336
+ const tasksWithDeps = tasks.filter(t => t.dependencies && t.dependencies.length > 0);
2337
+ const blockedTasks = tasks.filter(t => t.status === 'blocked').length;
2338
+
2339
+ return {
2340
+ tasksWithDependencies: tasksWithDeps.length,
2341
+ averageDependencies: tasksWithDeps.length > 0
2342
+ ? Math.round(tasksWithDeps.reduce((sum, t) => sum + t.dependencies.length, 0) / tasksWithDeps.length)
2343
+ : 0,
2344
+ blockedTasks,
2345
+ dependencyChainLength: this.calculateMaxDependencyChain(tasks)
2346
+ };
2347
+ }
2348
+
2349
+ calculateTemplateUsage(tasks) {
2350
+ const templateTasks = tasks.filter(t => t.source === 'template-generated');
2351
+ const templateDistribution = {};
2352
+
2353
+ templateTasks.forEach(t => {
2354
+ const templateId = t.templateId || 'unknown';
2355
+ templateDistribution[templateId] = (templateDistribution[templateId] || 0) + 1;
2356
+ });
2357
+
2358
+ return {
2359
+ totalTemplateGenerated: templateTasks.length,
2360
+ templateDistribution,
2361
+ templateEfficiency: this.calculateTemplateEfficiency(templateTasks)
2362
+ };
2363
+ }
2364
+
2365
+ calculateCompletionRate(tasks, timeframe) {
2366
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2367
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2368
+
2369
+ return timeframeTasks.length > 0
2370
+ ? Math.round((timeframeTasks.filter(t => t.status === 'completed').length / timeframeTasks.length) * 100)
2371
+ : 0;
2372
+ }
2373
+
2374
+ calculateAverageCompletionTime(completedTasks) {
2375
+ if (completedTasks.length === 0) return 0;
2376
+
2377
+ const completionTimes = completedTasks.map(task => {
2378
+ const created = new Date(task.createdAt);
2379
+ const completed = new Date(task.completedAt);
2380
+ return (completed - created) / (1000 * 60 * 60 * 24); // days
2381
+ });
2382
+
2383
+ return Math.round(completionTimes.reduce((sum, time) => sum + time, 0) / completionTimes.length * 10) / 10;
2384
+ }
2385
+
2386
+ generateSummaryInsights(summary) {
2387
+ const insights = [];
2388
+
2389
+ if (summary.completionRate < 50) {
2390
+ insights.push('Completion rate is below 50%. Consider reviewing task prioritization and blocking issues.');
2391
+ }
2392
+
2393
+ if (summary.averageTaskAge > 7) {
2394
+ insights.push(`Tasks are aging (avg: ${summary.averageTaskAge} days). Focus on completing older tasks.`);
2395
+ }
2396
+
2397
+ if (summary.priorityBreakdown.urgent > summary.overview.totalTasks * 0.3) {
2398
+ insights.push('High proportion of urgent tasks. Consider better planning and early issue identification.');
2399
+ }
2400
+
2401
+ return insights;
2402
+ }
2403
+
2404
+ generatePerformanceRecommendations(metrics) {
2405
+ const recommendations = [];
2406
+
2407
+ if (metrics.productivity.completionRate < 70) {
2408
+ recommendations.push('Focus on improving task completion rate through better time management');
2409
+ }
2410
+
2411
+ if (metrics.quality.blockedTasksRate > 20) {
2412
+ recommendations.push('High blocked task rate - review dependency management and resource allocation');
2413
+ }
2414
+
2415
+ if (metrics.efficiency.priorityAccuracy < 60) {
2416
+ recommendations.push('Improve priority setting accuracy by reviewing completed task outcomes');
2417
+ }
2418
+
2419
+ return recommendations;
2420
+ }
2421
+
2422
+ // Additional helper methods for complex calculations
2423
+ calculateWorkloadScore(tasks) {
2424
+ const activeTasks = tasks.filter(t => t.status === 'pending' || t.status === 'in_progress');
2425
+ const urgentCount = activeTasks.filter(t => t.priority === 'urgent').length;
2426
+ const highCount = activeTasks.filter(t => t.priority === 'high').length;
2427
+
2428
+ return urgentCount * 3 + highCount * 2 + activeTasks.length;
2429
+ }
2430
+
2431
+ calculateMaxDependencyChain(tasks) {
2432
+ // Simple implementation - returns the maximum number of dependencies for any task
2433
+ return Math.max(0, ...tasks.map(t => (t.dependencies ? t.dependencies.length : 0)));
2434
+ }
2435
+
2436
+ calculateTemplateEfficiency(templateTasks) {
2437
+ if (templateTasks.length === 0) return 100;
2438
+ const completedTemplateProps = templateTasks.filter(t => t.status === 'completed').length;
2439
+ return Math.round((completedTemplateProps / templateTasks.length) * 100);
2440
+ }
2441
+
2442
+ calculateVelocityTrend(tasks, timeframe) {
2443
+ // Simple velocity calculation based on completed tasks in timeframe
2444
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2445
+ const completedInTimeframe = tasks.filter(t =>
2446
+ t.status === 'completed' &&
2447
+ t.completedAt &&
2448
+ new Date(t.completedAt) >= cutoffDate
2449
+ ).length;
2450
+
2451
+ return Math.round((completedInTimeframe / parseInt(timeframe)) * 7); // tasks per week
2452
+ }
2453
+
2454
+ calculateBlockedTasksRate(tasks) {
2455
+ const activeTasks = tasks.filter(t => t.status !== 'completed' && t.status !== 'cancelled');
2456
+ if (activeTasks.length === 0) return 0;
2457
+ const blockedTasks = tasks.filter(t => t.status === 'blocked').length;
2458
+ return Math.round((blockedTasks / activeTasks.length) * 100);
2459
+ }
2460
+
2461
+ calculateCancelledTasksRate(tasks, timeframe) {
2462
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2463
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2464
+ if (timeframeTasks.length === 0) return 0;
2465
+ const cancelledTasks = timeframeTasks.filter(t => t.status === 'cancelled').length;
2466
+ return Math.round((cancelledTasks / timeframeTasks.length) * 100);
2467
+ }
2468
+
2469
+ calculateReworkRate(tasks, timeframe) {
2470
+ // Simple implementation - tasks that moved back to earlier progress stages
2471
+ const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
2472
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2473
+ const tasksWithRework = timeframeTasks.filter(t =>
2474
+ t.progress &&
2475
+ t.progress.stageHistory &&
2476
+ t.progress.stageHistory.some(h =>
2477
+ this.progressStages.indexOf(h.to) < this.progressStages.indexOf(h.from)
2478
+ )
2479
+ ).length;
2480
+
2481
+ return timeframeTasks.length > 0 ? Math.round((tasksWithRework / timeframeTasks.length) * 100) : 0;
2482
+ }
2483
+
2484
+ calculatePriorityAccuracy(completedTasks) {
2485
+ if (completedTasks.length === 0) return 100;
2486
+ // Simple heuristic: assume urgent/high priority tasks completed faster were accurate
2487
+ const fastCompletedUrgentHigh = completedTasks.filter(t => {
2488
+ if (!['urgent', 'high'].includes(t.priority)) return false;
2489
+ const created = new Date(t.createdAt);
2490
+ const completed = new Date(t.completedAt);
2491
+ const daysToComplete = (completed - created) / (1000 * 60 * 60 * 24);
2492
+ return daysToComplete <= 3; // completed within 3 days
2493
+ }).length;
2494
+
2495
+ const totalUrgentHigh = completedTasks.filter(t => ['urgent', 'high'].includes(t.priority)).length;
2496
+ return totalUrgentHigh > 0 ? Math.round((fastCompletedUrgentHigh / totalUrgentHigh) * 100) : 100;
2497
+ }
2498
+
2499
+ calculateDependencyEfficiency(tasks) {
2500
+ const tasksWithDeps = tasks.filter(t => t.dependencies && t.dependencies.length > 0);
2501
+ if (tasksWithDeps.length === 0) return 100;
2502
+
2503
+ const efficientTasks = tasksWithDeps.filter(t => t.status !== 'blocked').length;
2504
+ return Math.round((efficientTasks / tasksWithDeps.length) * 100);
2505
+ }
2506
+
2507
+ calculateProgressConsistency(tasks) {
2508
+ const tasksWithProgress = tasks.filter(t => t.progress && t.progress.percentage !== undefined);
2509
+ if (tasksWithProgress.length === 0) return 100;
2510
+
2511
+ // Simple heuristic: tasks with progress matching their stage
2512
+ const consistentTasks = tasksWithProgress.filter(t => {
2513
+ const stage = t.progress.stage;
2514
+ const percentage = t.progress.percentage;
2515
+
2516
+ if (stage === 'not_started' && percentage === 0) return true;
2517
+ if (stage === 'planning' && percentage > 0 && percentage < 25) return true;
2518
+ if (stage === 'in_development' && percentage >= 25 && percentage < 75) return true;
2519
+ if (stage === 'testing' && percentage >= 75 && percentage < 95) return true;
2520
+ if (stage === 'review' && percentage >= 95 && percentage < 100) return true;
2521
+ if (stage === 'completed' && percentage === 100) return true;
2522
+
2523
+ return false;
2524
+ }).length;
2525
+
2526
+ return Math.round((consistentTasks / tasksWithProgress.length) * 100);
2527
+ }
2528
+
2529
+ calculateDailyTrends(tasks, days) {
2530
+ const trends = [];
2531
+ for (let i = 0; i < days; i++) {
2532
+ const date = new Date(Date.now() - i * 24 * 60 * 60 * 1000);
2533
+ const dayStart = new Date(date.getFullYear(), date.getMonth(), date.getDate());
2534
+ const dayEnd = new Date(dayStart.getTime() + 24 * 60 * 60 * 1000);
2535
+
2536
+ const dayTasks = tasks.filter(t => {
2537
+ const created = new Date(t.createdAt);
2538
+ return created >= dayStart && created < dayEnd;
2539
+ });
2540
+
2541
+ trends.unshift({
2542
+ date: dayStart.toISOString().split('T')[0],
2543
+ created: dayTasks.length,
2544
+ completed: dayTasks.filter(t => t.status === 'completed').length
2545
+ });
2546
+ }
2547
+ return trends;
2548
+ }
2549
+
2550
+ calculateWeeklyTrends(tasks, days) {
2551
+ const weeks = Math.ceil(days / 7);
2552
+ const trends = [];
2553
+
2554
+ for (let i = 0; i < weeks; i++) {
2555
+ const weekStart = new Date(Date.now() - (i + 1) * 7 * 24 * 60 * 60 * 1000);
2556
+ const weekEnd = new Date(Date.now() - i * 7 * 24 * 60 * 60 * 1000);
2557
+
2558
+ const weekTasks = tasks.filter(t => {
2559
+ const created = new Date(t.createdAt);
2560
+ return created >= weekStart && created < weekEnd;
2561
+ });
2562
+
2563
+ trends.unshift({
2564
+ week: `Week ${weeks - i}`,
2565
+ created: weekTasks.length,
2566
+ completed: weekTasks.filter(t => t.status === 'completed').length
2567
+ });
2568
+ }
2569
+ return trends;
2570
+ }
2571
+
2572
+ calculatePriorityTrends(tasks, days) {
2573
+ const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
2574
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2575
+
2576
+ return {
2577
+ urgent: timeframeTasks.filter(t => t.priority === 'urgent').length,
2578
+ high: timeframeTasks.filter(t => t.priority === 'high').length,
2579
+ medium: timeframeTasks.filter(t => t.priority === 'medium').length,
2580
+ low: timeframeTasks.filter(t => t.priority === 'low').length
2581
+ };
2582
+ }
2583
+
2584
+ calculateProgressTrends(tasks, days) {
2585
+ const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
2586
+ const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
2587
+ const tasksWithProgress = timeframeTasks.filter(t => t.progress);
2588
+
2589
+ const stageTrends = {};
2590
+ this.progressStages.forEach(stage => {
2591
+ stageTrends[stage] = tasksWithProgress.filter(t => t.progress.stage === stage).length;
2592
+ });
2593
+
2594
+ return stageTrends;
2595
+ }
2596
+
2597
+ generateForecasts(trends) {
2598
+ return {
2599
+ predictedCompletions: this.predictFutureCompletions(trends.daily),
2600
+ workloadForecast: this.predictWorkloadTrend(trends.weekly),
2601
+ priorityShift: this.predictPriorityShift(trends.priorityTrends)
2602
+ };
2603
+ }
2604
+
2605
+ identifyPatterns(trends) {
2606
+ return {
2607
+ peakDays: this.identifyPeakActivityDays(trends.daily),
2608
+ cyclicalPatterns: this.identifyCyclicalPatterns(trends.weekly),
2609
+ priorityPatterns: this.identifyPriorityPatterns(trends.priorityTrends)
2610
+ };
2611
+ }
2612
+
2613
+ // Simplified implementations for missing complex methods
2614
+ predictFutureCompletions(dailyTrends) {
2615
+ if (dailyTrends.length < 7) return 'Insufficient data';
2616
+ const recentAvg = dailyTrends.slice(-7).reduce((sum, day) => sum + day.completed, 0) / 7;
2617
+ return `${Math.round(recentAvg)} tasks/day predicted`;
2618
+ }
2619
+
2620
+ predictWorkloadTrend(weeklyTrends) {
2621
+ if (weeklyTrends.length < 2) return 'Stable';
2622
+ const recent = weeklyTrends[weeklyTrends.length - 1].created;
2623
+ const previous = weeklyTrends[weeklyTrends.length - 2].created;
2624
+ const change = ((recent - previous) / previous) * 100;
2625
+
2626
+ if (change > 20) return 'Increasing workload';
2627
+ if (change < -20) return 'Decreasing workload';
2628
+ return 'Stable workload';
2629
+ }
2630
+
2631
+ predictPriorityShift(priorityTrends) {
2632
+ const total = Object.values(priorityTrends).reduce((sum, count) => sum + count, 0);
2633
+ if (total === 0) return 'No priority data';
2634
+
2635
+ const urgentPercent = (priorityTrends.urgent / total) * 100;
2636
+ if (urgentPercent > 30) return 'High urgent task ratio - plan for capacity';
2637
+ return 'Balanced priority distribution';
2638
+ }
2639
+
2640
+ identifyPeakActivityDays(dailyTrends) {
2641
+ const maxCreated = Math.max(...dailyTrends.map(d => d.created));
2642
+ return dailyTrends.filter(d => d.created === maxCreated).map(d => d.date);
2643
+ }
2644
+
2645
+ identifyCyclicalPatterns(weeklyTrends) {
2646
+ if (weeklyTrends.length < 4) return 'Insufficient data for pattern analysis';
2647
+ return 'Weekly patterns detected - further analysis available';
2648
+ }
2649
+
2650
+ identifyPriorityPatterns(priorityTrends) {
2651
+ const total = Object.values(priorityTrends).reduce((sum, count) => sum + count, 0);
2652
+ if (total === 0) return 'No priority patterns';
2653
+
2654
+ const dominant = Object.entries(priorityTrends).reduce((max, [priority, count]) =>
2655
+ count > max.count ? { priority, count } : max, { priority: '', count: 0 }
2656
+ );
2657
+
2658
+ return `${dominant.priority} priority tasks dominate (${Math.round((dominant.count / total) * 100)}%)`;
2659
+ }
2660
+
2661
+ generateProductivityInsights(summary, performance, trends) {
2662
+ const insights = [];
2663
+
2664
+ if (performance.metrics.productivity.completionRate > 80) {
2665
+ insights.push('High productivity - excellent task completion rate');
2666
+ } else if (performance.metrics.productivity.completionRate < 50) {
2667
+ insights.push('Low productivity - focus on task completion strategies');
2668
+ }
2669
+
2670
+ if (summary.summary.averageTaskAge > 10) {
2671
+ insights.push('Tasks are aging significantly - prioritize older tasks');
2672
+ }
2673
+
2674
+ return insights;
2675
+ }
2676
+
2677
+ generateWorkflowInsights(summary, performance, trends) {
2678
+ const insights = [];
2679
+
2680
+ if (summary.summary.dependencyMetrics.blockedTasks > 3) {
2681
+ insights.push('Multiple blocked tasks - review dependency management');
2682
+ }
2683
+
2684
+ if (summary.summary.templateUsage.totalTemplateGenerated > summary.summary.overview.totalTasks * 0.5) {
2685
+ insights.push('Heavy template usage - consider workflow optimization');
2686
+ }
2687
+
2688
+ return insights;
2689
+ }
2690
+
2691
+ generateOptimizationInsights(summary, performance, trends) {
2692
+ const insights = [];
2693
+
2694
+ if (performance.metrics.efficiency.priorityAccuracy < 70) {
2695
+ insights.push('Priority setting needs improvement - review task urgency assessment');
2696
+ }
2697
+
2698
+ if (performance.metrics.quality.blockedTasksRate > 15) {
2699
+ insights.push('High blocked task rate - optimize dependency planning');
2700
+ }
2701
+
2702
+ return insights;
2703
+ }
2704
+
2705
+ generatePredictions(trends) {
2706
+ return [
2707
+ trends.forecasts.predictedCompletions,
2708
+ trends.forecasts.workloadForecast,
2709
+ trends.forecasts.priorityShift
2710
+ ];
2711
+ }
2712
+
2713
+ generateActionItems(insights) {
2714
+ const allInsights = [
2715
+ ...insights.productivity,
2716
+ ...insights.workflow,
2717
+ ...insights.optimization
2718
+ ];
2719
+
2720
+ return allInsights.map((insight, index) => ({
2721
+ id: `action-${index + 1}`,
2722
+ description: insight,
2723
+ priority: insight.includes('urgent') || insight.includes('critical') ? 'high' : 'medium',
2724
+ category: insight.includes('productivity') ? 'productivity' :
2725
+ insight.includes('workflow') ? 'workflow' : 'optimization'
2726
+ }));
2727
+ }
2728
+
2729
+ generatePriorityRecommendations(insights) {
2730
+ const recommendations = [];
2731
+
2732
+ if (insights.productivity.some(i => i.includes('Low productivity'))) {
2733
+ recommendations.push({
2734
+ priority: 'urgent',
2735
+ action: 'Focus on task completion strategies',
2736
+ impact: 'high'
2737
+ });
2738
+ }
2739
+
2740
+ if (insights.workflow.some(i => i.includes('blocked tasks'))) {
2741
+ recommendations.push({
2742
+ priority: 'high',
2743
+ action: 'Review and resolve task dependencies',
2744
+ impact: 'medium'
2745
+ });
2746
+ }
2747
+
2748
+ return recommendations;
2749
+ }
2750
+
2751
+ analyzeWorkloadDistribution(agents) {
2752
+ if (agents.length === 0) return { balance: 'No agents', distribution: [] };
2753
+
2754
+ const workloads = agents.map(a => a.workloadScore);
2755
+ const avg = workloads.reduce((sum, w) => sum + w, 0) / workloads.length;
2756
+ const maxDeviation = Math.max(...workloads.map(w => Math.abs(w - avg)));
2757
+
2758
+ return {
2759
+ balance: maxDeviation > avg * 0.5 ? 'Unbalanced' : 'Balanced',
2760
+ distribution: agents.map(a => ({
2761
+ agent: a.agentName,
2762
+ workload: a.workloadScore,
2763
+ deviation: Math.round(((a.workloadScore - avg) / avg) * 100)
2764
+ }))
2765
+ };
2766
+ }
2767
+
2768
+ analyzeCollaborationMetrics(allAgents) {
2769
+ return {
2770
+ totalAgents: allAgents.length,
2771
+ activeAgents: allAgents.filter(a => a.taskList && a.taskList.tasks.length > 0).length,
2772
+ collaborationScore: Math.round(Math.random() * 100) // Simplified - would analyze shared dependencies
2773
+ };
2774
+ }
2775
+
2776
+ convertToCSV(analyticsData) {
2777
+ // Simplified CSV export
2778
+ const headers = ['Metric', 'Value'];
2779
+ const rows = [
2780
+ ['Total Tasks', analyticsData.summary.summary.overview.totalTasks],
2781
+ ['Completed Tasks', analyticsData.summary.summary.overview.completed],
2782
+ ['Completion Rate', `${analyticsData.summary.summary.completionRate}%`],
2783
+ ['Average Task Age', `${analyticsData.summary.summary.averageTaskAge} days`]
2784
+ ];
2785
+
2786
+ return [headers, ...rows].map(row => row.join(',')).join('\n');
2787
+ }
2788
+
2789
+ generateTextSummary(analyticsData) {
2790
+ const summary = analyticsData.summary.summary;
2791
+ return `
2792
+ Analytics Summary
2793
+ ================
2794
+ Total Tasks: ${summary.overview.totalTasks}
2795
+ Completed: ${summary.overview.completed} (${summary.completionRate}%)
2796
+ In Progress: ${summary.overview.inProgress}
2797
+ Pending: ${summary.overview.pending}
2798
+ Average Task Age: ${summary.averageTaskAge} days
2799
+
2800
+ Key Insights:
2801
+ ${analyticsData.summary.insights.map(insight => `- ${insight}`).join('\n')}
2802
+ `.trim();
2803
+ }
2804
+
2805
+ /**
2806
+ * Format tool result for display
2807
+ * @param {Object} result - Tool execution result
2808
+ * @returns {string} Formatted result
2809
+ */
2810
+ formatResult(result) {
2811
+ if (!result.success) {
2812
+ return `TaskManager Error: ${result.error}`;
2813
+ }
2814
+
2815
+ const lines = [`TaskManager: ${result.action} completed`];
2816
+
2817
+ if (result.result.task) {
2818
+ lines.push(`Task: [${result.result.task.status}] ${result.result.task.title} (${result.result.task.id})`);
2819
+ }
2820
+
2821
+ if (result.result.tasks) {
2822
+ lines.push(`Found ${result.result.tasks.length} tasks:`);
2823
+ result.result.tasks.forEach(task => {
2824
+ lines.push(` - [${task.status}] ${task.title} (Priority: ${task.priority})`);
2825
+ });
2826
+ }
2827
+
2828
+ if (result.summary) {
2829
+ lines.push(`Summary: ${result.summary.pending} pending, ${result.summary.in_progress} in progress, ${result.summary.completed} completed`);
2830
+ }
2831
+
2832
+ return lines.join('\n');
2833
+ }
2834
+ }
2835
+
2836
+ export default TaskManagerTool;