@poolzin/pool-bot 2026.3.11 → 2026.3.14

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 (195) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/dist/.buildstamp +1 -1
  3. package/dist/agents/checkpoint-manager.js +291 -0
  4. package/dist/agents/poolbot-tools.js +5 -0
  5. package/dist/agents/subagent-announce-reliability.js +160 -0
  6. package/dist/agents/tool-result-truncation.js +299 -0
  7. package/dist/agents/tools/nodes-file-tool.js +197 -0
  8. package/dist/build-info.json +3 -3
  9. package/dist/cli/config-cli.js +60 -0
  10. package/dist/cron/cron-improvements.js +195 -0
  11. package/dist/discord/discord-improvements.js +167 -0
  12. package/dist/gateway/auth-rate-limit.js +19 -0
  13. package/dist/gateway/auth.js +41 -0
  14. package/dist/gateway/gateway-improvements.js +294 -0
  15. package/dist/gateway/node-command-policy.js +7 -2
  16. package/dist/infra/net/ssrf.js +15 -2
  17. package/dist/infra/shell-security.js +201 -0
  18. package/dist/memory/memory-improvements.js +239 -0
  19. package/dist/node-host/runner.js +146 -79
  20. package/dist/security/prototype-pollution.js +141 -0
  21. package/dist/security/webhook-security.js +253 -0
  22. package/dist/shared/net/ip.js +52 -1
  23. package/dist/slack/slack-improvements.js +225 -0
  24. package/dist/telegram/telegram-improvements.js +220 -0
  25. package/dist/ui-plugins/ui-plugins-improvements.js +191 -0
  26. package/docs/ANALISE_OPENCLAW_PROFISSIONAL.md +520 -0
  27. package/docs/competitive-analysis.md +421 -0
  28. package/docs/implementation-analysis.md +393 -0
  29. package/docs/plans/2026-03-11-file-operations-security-hardening.md +307 -0
  30. package/docs/plans/2026-03-11-integracao-projetos-poolbot.md +666 -0
  31. package/docs/refactor/plugin-development-guide.md +281 -0
  32. package/extensions/agency-agents/README.md +301 -0
  33. package/extensions/agency-agents/agents/CONTRIBUTING.md +353 -0
  34. package/extensions/agency-agents/agents/README.md +602 -0
  35. package/extensions/agency-agents/agents/design/design-brand-guardian.md +320 -0
  36. package/extensions/agency-agents/agents/design/design-image-prompt-engineer.md +234 -0
  37. package/extensions/agency-agents/agents/design/design-ui-designer.md +381 -0
  38. package/extensions/agency-agents/agents/design/design-ux-architect.md +467 -0
  39. package/extensions/agency-agents/agents/design/design-ux-researcher.md +327 -0
  40. package/extensions/agency-agents/agents/design/design-visual-storyteller.md +147 -0
  41. package/extensions/agency-agents/agents/design/design-whimsy-injector.md +436 -0
  42. package/extensions/agency-agents/agents/engineering/engineering-ai-engineer.md +144 -0
  43. package/extensions/agency-agents/agents/engineering/engineering-backend-architect.md +233 -0
  44. package/extensions/agency-agents/agents/engineering/engineering-devops-automator.md +374 -0
  45. package/extensions/agency-agents/agents/engineering/engineering-frontend-developer.md +223 -0
  46. package/extensions/agency-agents/agents/engineering/engineering-mobile-app-builder.md +491 -0
  47. package/extensions/agency-agents/agents/engineering/engineering-rapid-prototyper.md +460 -0
  48. package/extensions/agency-agents/agents/engineering/engineering-security-engineer.md +275 -0
  49. package/extensions/agency-agents/agents/engineering/engineering-senior-developer.md +174 -0
  50. package/extensions/agency-agents/agents/examples/README.md +48 -0
  51. package/extensions/agency-agents/agents/examples/nexus-spatial-discovery.md +852 -0
  52. package/extensions/agency-agents/agents/examples/workflow-landing-page.md +119 -0
  53. package/extensions/agency-agents/agents/examples/workflow-startup-mvp.md +155 -0
  54. package/extensions/agency-agents/agents/integrations/README.md +117 -0
  55. package/extensions/agency-agents/agents/integrations/aider/README.md +38 -0
  56. package/extensions/agency-agents/agents/integrations/antigravity/README.md +49 -0
  57. package/extensions/agency-agents/agents/integrations/claude-code/README.md +31 -0
  58. package/extensions/agency-agents/agents/integrations/cursor/README.md +38 -0
  59. package/extensions/agency-agents/agents/integrations/gemini-cli/README.md +36 -0
  60. package/extensions/agency-agents/agents/integrations/opencode/README.md +58 -0
  61. package/extensions/agency-agents/agents/integrations/windsurf/README.md +26 -0
  62. package/extensions/agency-agents/agents/marketing/marketing-app-store-optimizer.md +319 -0
  63. package/extensions/agency-agents/agents/marketing/marketing-content-creator.md +52 -0
  64. package/extensions/agency-agents/agents/marketing/marketing-growth-hacker.md +52 -0
  65. package/extensions/agency-agents/agents/marketing/marketing-instagram-curator.md +111 -0
  66. package/extensions/agency-agents/agents/marketing/marketing-reddit-community-builder.md +121 -0
  67. package/extensions/agency-agents/agents/marketing/marketing-social-media-strategist.md +123 -0
  68. package/extensions/agency-agents/agents/marketing/marketing-tiktok-strategist.md +123 -0
  69. package/extensions/agency-agents/agents/marketing/marketing-twitter-engager.md +124 -0
  70. package/extensions/agency-agents/agents/marketing/marketing-wechat-official-account.md +143 -0
  71. package/extensions/agency-agents/agents/marketing/marketing-xiaohongshu-specialist.md +136 -0
  72. package/extensions/agency-agents/agents/marketing/marketing-zhihu-strategist.md +160 -0
  73. package/extensions/agency-agents/agents/product/product-feedback-synthesizer.md +117 -0
  74. package/extensions/agency-agents/agents/product/product-sprint-prioritizer.md +152 -0
  75. package/extensions/agency-agents/agents/product/product-trend-researcher.md +157 -0
  76. package/extensions/agency-agents/agents/project-management/project-management-experiment-tracker.md +196 -0
  77. package/extensions/agency-agents/agents/project-management/project-management-project-shepherd.md +192 -0
  78. package/extensions/agency-agents/agents/project-management/project-management-studio-operations.md +198 -0
  79. package/extensions/agency-agents/agents/project-management/project-management-studio-producer.md +201 -0
  80. package/extensions/agency-agents/agents/project-management/project-manager-senior.md +133 -0
  81. package/extensions/agency-agents/agents/scripts/convert.sh +362 -0
  82. package/extensions/agency-agents/agents/scripts/install.sh +465 -0
  83. package/extensions/agency-agents/agents/scripts/lint-agents.sh +115 -0
  84. package/extensions/agency-agents/agents/spatial-computing/macos-spatial-metal-engineer.md +335 -0
  85. package/extensions/agency-agents/agents/spatial-computing/terminal-integration-specialist.md +68 -0
  86. package/extensions/agency-agents/agents/spatial-computing/visionos-spatial-engineer.md +52 -0
  87. package/extensions/agency-agents/agents/spatial-computing/xr-cockpit-interaction-specialist.md +30 -0
  88. package/extensions/agency-agents/agents/spatial-computing/xr-immersive-developer.md +30 -0
  89. package/extensions/agency-agents/agents/spatial-computing/xr-interface-architect.md +30 -0
  90. package/extensions/agency-agents/agents/specialized/agentic-identity-trust.md +367 -0
  91. package/extensions/agency-agents/agents/specialized/agents-orchestrator.md +365 -0
  92. package/extensions/agency-agents/agents/specialized/data-analytics-reporter.md +52 -0
  93. package/extensions/agency-agents/agents/specialized/data-consolidation-agent.md +58 -0
  94. package/extensions/agency-agents/agents/specialized/lsp-index-engineer.md +312 -0
  95. package/extensions/agency-agents/agents/specialized/report-distribution-agent.md +63 -0
  96. package/extensions/agency-agents/agents/specialized/sales-data-extraction-agent.md +65 -0
  97. package/extensions/agency-agents/agents/strategy/EXECUTIVE-BRIEF.md +95 -0
  98. package/extensions/agency-agents/agents/strategy/QUICKSTART.md +194 -0
  99. package/extensions/agency-agents/agents/strategy/coordination/agent-activation-prompts.md +401 -0
  100. package/extensions/agency-agents/agents/strategy/coordination/handoff-templates.md +357 -0
  101. package/extensions/agency-agents/agents/strategy/nexus-strategy.md +1110 -0
  102. package/extensions/agency-agents/agents/strategy/playbooks/phase-0-discovery.md +178 -0
  103. package/extensions/agency-agents/agents/strategy/playbooks/phase-1-strategy.md +238 -0
  104. package/extensions/agency-agents/agents/strategy/playbooks/phase-2-foundation.md +278 -0
  105. package/extensions/agency-agents/agents/strategy/playbooks/phase-3-build.md +286 -0
  106. package/extensions/agency-agents/agents/strategy/playbooks/phase-4-hardening.md +332 -0
  107. package/extensions/agency-agents/agents/strategy/playbooks/phase-5-launch.md +277 -0
  108. package/extensions/agency-agents/agents/strategy/playbooks/phase-6-operate.md +318 -0
  109. package/extensions/agency-agents/agents/strategy/runbooks/scenario-enterprise-feature.md +157 -0
  110. package/extensions/agency-agents/agents/strategy/runbooks/scenario-incident-response.md +217 -0
  111. package/extensions/agency-agents/agents/strategy/runbooks/scenario-marketing-campaign.md +187 -0
  112. package/extensions/agency-agents/agents/strategy/runbooks/scenario-startup-mvp.md +154 -0
  113. package/extensions/agency-agents/agents/support/support-analytics-reporter.md +363 -0
  114. package/extensions/agency-agents/agents/support/support-executive-summary-generator.md +210 -0
  115. package/extensions/agency-agents/agents/support/support-finance-tracker.md +440 -0
  116. package/extensions/agency-agents/agents/support/support-infrastructure-maintainer.md +616 -0
  117. package/extensions/agency-agents/agents/support/support-legal-compliance-checker.md +586 -0
  118. package/extensions/agency-agents/agents/support/support-support-responder.md +583 -0
  119. package/extensions/agency-agents/agents/testing/testing-accessibility-auditor.md +313 -0
  120. package/extensions/agency-agents/agents/testing/testing-api-tester.md +304 -0
  121. package/extensions/agency-agents/agents/testing/testing-evidence-collector.md +208 -0
  122. package/extensions/agency-agents/agents/testing/testing-performance-benchmarker.md +266 -0
  123. package/extensions/agency-agents/agents/testing/testing-reality-checker.md +236 -0
  124. package/extensions/agency-agents/agents/testing/testing-test-results-analyzer.md +303 -0
  125. package/extensions/agency-agents/agents/testing/testing-tool-evaluator.md +392 -0
  126. package/extensions/agency-agents/agents/testing/testing-workflow-optimizer.md +448 -0
  127. package/extensions/agency-agents/index.ts +733 -0
  128. package/extensions/agency-agents/node_modules/.bin/jiti +21 -0
  129. package/extensions/agency-agents/node_modules/.bin/tsc +21 -0
  130. package/extensions/agency-agents/node_modules/.bin/tsserver +21 -0
  131. package/extensions/agency-agents/node_modules/.bin/tsx +21 -0
  132. package/extensions/agency-agents/node_modules/.bin/vite +21 -0
  133. package/extensions/agency-agents/node_modules/.bin/vitest +21 -0
  134. package/extensions/agency-agents/node_modules/.bin/yaml +21 -0
  135. package/extensions/agency-agents/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  136. package/extensions/agency-agents/package.json +25 -0
  137. package/extensions/agency-agents/src/AgencyAgentsService.test.ts +443 -0
  138. package/extensions/agency-agents/src/AgencyAgentsService.ts +288 -0
  139. package/extensions/agency-agents/src/types.ts +147 -0
  140. package/extensions/agency-agents/vitest.config.ts +8 -0
  141. package/extensions/hexstrike-ai/README.md +98 -0
  142. package/extensions/hexstrike-ai/node_modules/.bin/tsc +21 -0
  143. package/extensions/hexstrike-ai/node_modules/.bin/tsserver +21 -0
  144. package/extensions/hexstrike-ai/package.json +29 -0
  145. package/extensions/hexstrike-ai/poolbot.plugin.json +31 -0
  146. package/extensions/hexstrike-ai/src/client.ts +91 -0
  147. package/extensions/hexstrike-ai/src/index.ts +170 -0
  148. package/extensions/hexstrike-ai/src/server/hexstrike_mcp.py +5470 -0
  149. package/extensions/hexstrike-ai/src/server/hexstrike_server.py +17289 -0
  150. package/extensions/hexstrike-ai/src/server/requirements.txt +84 -0
  151. package/extensions/hexstrike-ai/src/server-manager.ts +83 -0
  152. package/extensions/hexstrike-ai/tsconfig.json +20 -0
  153. package/extensions/hexstrike-bridge/package.json +1 -1
  154. package/extensions/hexstrike-bridge/poolbot.plugin.json +23 -0
  155. package/extensions/mcp-server/poolbot.plugin.json +10 -0
  156. package/extensions/page-agent/README.md +159 -0
  157. package/extensions/page-agent/index.ts +595 -0
  158. package/extensions/page-agent/node_modules/.bin/jiti +21 -0
  159. package/extensions/page-agent/node_modules/.bin/playwright +21 -0
  160. package/extensions/page-agent/node_modules/.bin/tsc +21 -0
  161. package/extensions/page-agent/node_modules/.bin/tsserver +21 -0
  162. package/extensions/page-agent/node_modules/.bin/tsx +21 -0
  163. package/extensions/page-agent/node_modules/.bin/vitest +21 -0
  164. package/extensions/page-agent/node_modules/.bin/yaml +21 -0
  165. package/extensions/page-agent/package.json +43 -0
  166. package/extensions/page-agent/src/PageAgentService.test.ts +517 -0
  167. package/extensions/page-agent/src/PageAgentService.ts +636 -0
  168. package/extensions/page-agent/src/PoolBotPageController.test.ts +358 -0
  169. package/extensions/page-agent/src/PoolBotPageController.ts +245 -0
  170. package/extensions/page-agent/src/index.ts +20 -0
  171. package/extensions/page-agent/src/tools.test.ts +231 -0
  172. package/extensions/page-agent/src/tools.ts +167 -0
  173. package/extensions/page-agent/src/types.ts +198 -0
  174. package/extensions/template/README.md +101 -0
  175. package/extensions/template/index.ts +38 -0
  176. package/extensions/template/package.json +15 -0
  177. package/extensions/template/poolbot.plugin.json +10 -0
  178. package/extensions/xyops/README.md +227 -0
  179. package/extensions/xyops/index.ts +342 -0
  180. package/extensions/xyops/node_modules/.bin/jiti +21 -0
  181. package/extensions/xyops/node_modules/.bin/tsc +21 -0
  182. package/extensions/xyops/node_modules/.bin/tsserver +21 -0
  183. package/extensions/xyops/node_modules/.bin/tsx +21 -0
  184. package/extensions/xyops/node_modules/.bin/vitest +21 -0
  185. package/extensions/xyops/node_modules/.bin/yaml +21 -0
  186. package/extensions/xyops/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  187. package/extensions/xyops/package.json +39 -0
  188. package/extensions/xyops/src/client.test.ts +467 -0
  189. package/extensions/xyops/src/client.ts +157 -0
  190. package/extensions/xyops/src/types.ts +147 -0
  191. package/extensions/xyops/vitest.config.ts +8 -0
  192. package/package.json +1 -1
  193. package/extensions/mavalie/README.md +0 -97
  194. package/extensions/mavalie/package.json +0 -15
  195. package/extensions/mavalie/src/index.ts +0 -62
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/jiti@2.6.1/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/jiti-cli.mjs" "$@"
19
+ else
20
+ exec node "$basedir/../../../../node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/jiti-cli.mjs" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsc" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/tsx@4.21.0/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/cli.mjs" "$@"
19
+ else
20
+ exec node "$basedir/../../../../node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/cli.mjs" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/vite.js" "$@"
19
+ else
20
+ exec node "$basedir/../../../../node_modules/.pnpm/vite@7.3.1_@types+node@22.19.15_jiti@2.6.1_lightningcss@1.30.2_tsx@4.21.0_yaml@2.8.2/node_modules/vite/bin/vite.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.15_@vitest+browser@4.0.18_vite@7.3.1_@types+node@25.2.3__6cb5e51e836830cd2cffacfc8438d429/node_modules/vitest/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.15_@vitest+browser@4.0.18_vite@7.3.1_@types+node@25.2.3__6cb5e51e836830cd2cffacfc8438d429/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.15_@vitest+browser@4.0.18_vite@7.3.1_@types+node@25.2.3__6cb5e51e836830cd2cffacfc8438d429/node_modules/vitest/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/vitest@3.2.4_@types+node@22.19.15_@vitest+browser@4.0.18_vite@7.3.1_@types+node@25.2.3__6cb5e51e836830cd2cffacfc8438d429/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
19
+ else
20
+ exec node "$basedir/../vitest/vitest.mjs" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/yaml@2.8.2/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/yaml@2.8.2/node_modules:/Users/pool/Documents/GitHub/pool-bot/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/bin.mjs" "$@"
19
+ else
20
+ exec node "$basedir/../../../../node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/bin.mjs" "$@"
21
+ fi
@@ -0,0 +1 @@
1
+ {"version":"3.2.4","results":[[":src/AgencyAgentsService.test.ts",{"duration":416.220958,"failed":false}]]}
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@poolbot/agency-agents",
3
+ "version": "2026.3.13",
4
+ "description": "Agency Agents - AI Specialists for PoolBot (Frontend, Backend, DevOps, etc.)",
5
+ "type": "module",
6
+ "main": "index.ts",
7
+ "scripts": {
8
+ "test": "vitest run",
9
+ "test:watch": "vitest"
10
+ },
11
+ "dependencies": {
12
+ "@sinclair/typebox": "^0.34.0"
13
+ },
14
+ "devDependencies": {
15
+ "@types/node": "^22.0.0",
16
+ "typescript": "^5.0.0",
17
+ "vitest": "^3.0.0"
18
+ },
19
+ "poolbot": {
20
+ "plugin": true
21
+ },
22
+ "keywords": ["agents", "ai", "specialists", "engineering", "automation"],
23
+ "author": "PoolBot Team",
24
+ "license": "MIT"
25
+ }
@@ -0,0 +1,443 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest'
2
+ import { AgencyAgentsService } from './AgencyAgentsService.js'
3
+ import type { AgencyAgent } from './types.js'
4
+
5
+ describe('AgencyAgentsService', () => {
6
+ let service: AgencyAgentsService
7
+
8
+ const mockAgent: AgencyAgent = {
9
+ name: 'FrontendDev',
10
+ description: 'Frontend development specialist',
11
+ color: '#3b82f6',
12
+ category: 'engineering',
13
+ content: 'Expert in React, Vue, and modern CSS',
14
+ capabilities: ['React', 'Vue', 'CSS', 'TypeScript'],
15
+ tools: ['browser', 'code-editor'],
16
+ }
17
+
18
+ const mockDesigner: AgencyAgent = {
19
+ name: 'UXDesigner',
20
+ description: 'UX/UI design specialist',
21
+ color: '#ec4899',
22
+ category: 'design',
23
+ content: 'Expert in user research and interface design',
24
+ capabilities: ['Figma', 'User Research', 'Prototyping'],
25
+ tools: ['figma', 'design-system'],
26
+ }
27
+
28
+ beforeEach(() => {
29
+ service = new AgencyAgentsService()
30
+ })
31
+
32
+ describe('Agent Management', () => {
33
+ it('should register an agent', () => {
34
+ service.registerAgent(mockAgent)
35
+ const retrieved = service.getAgent('frontenddev')
36
+ expect(retrieved).toEqual(mockAgent)
37
+ })
38
+
39
+ it('should get agent case-insensitively', () => {
40
+ service.registerAgent(mockAgent)
41
+ const retrieved = service.getAgent('FRONTENDDEV')
42
+ expect(retrieved).toEqual(mockAgent)
43
+ })
44
+
45
+ it('should return undefined for non-existent agent', () => {
46
+ const retrieved = service.getAgent('nonexistent')
47
+ expect(retrieved).toBeUndefined()
48
+ })
49
+
50
+ it('should list all agents', () => {
51
+ service.registerAgent(mockAgent)
52
+ service.registerAgent(mockDesigner)
53
+ const agents = service.listAgents()
54
+ expect(agents).toHaveLength(2)
55
+ expect(agents.map(a => a.name)).toContain('FrontendDev')
56
+ expect(agents.map(a => a.name)).toContain('UXDesigner')
57
+ })
58
+
59
+ it('should filter agents by category', () => {
60
+ service.registerAgent(mockAgent)
61
+ service.registerAgent(mockDesigner)
62
+ const engineeringAgents = service.listAgents('engineering')
63
+ expect(engineeringAgents).toHaveLength(1)
64
+ expect(engineeringAgents[0].name).toBe('FrontendDev')
65
+ })
66
+
67
+ it('should filter agents case-insensitively by category', () => {
68
+ service.registerAgent(mockAgent)
69
+ const agents = service.listAgents('ENGINEERING')
70
+ expect(agents).toHaveLength(1)
71
+ })
72
+ })
73
+
74
+ describe('Agent Matching', () => {
75
+ beforeEach(() => {
76
+ service.registerAgent(mockAgent)
77
+ service.registerAgent(mockDesigner)
78
+ })
79
+
80
+ it('should find agents matching task keywords', () => {
81
+ const matches = service.findAgentsForTask('Build a React component')
82
+ expect(matches.length).toBeGreaterThan(0)
83
+ expect(matches[0].agent.name).toBe('FrontendDev')
84
+ expect(matches[0].score).toBeGreaterThan(0)
85
+ })
86
+
87
+ it('should score agents based on category relevance', () => {
88
+ const matches = service.findAgentsForTask('Create a design system')
89
+ const designerMatch = matches.find(m => m.agent.name === 'UXDesigner')
90
+ expect(designerMatch).toBeDefined()
91
+ expect(designerMatch!.score).toBeGreaterThan(0)
92
+ })
93
+
94
+ it('should boost score for frontend tasks', () => {
95
+ const matches = service.findAgentsForTask('frontend development')
96
+ const frontendMatch = matches.find(m => m.agent.name === 'FrontendDev')
97
+ expect(frontendMatch).toBeDefined()
98
+ expect(frontendMatch!.score).toBeGreaterThanOrEqual(5)
99
+ })
100
+
101
+ it('should boost score for design tasks', () => {
102
+ const matches = service.findAgentsForTask('design mockups')
103
+ const designerMatch = matches.find(m => m.agent.name === 'UXDesigner')
104
+ expect(designerMatch).toBeDefined()
105
+ expect(designerMatch!.score).toBeGreaterThanOrEqual(5)
106
+ })
107
+
108
+ it('should return empty array for no matches', () => {
109
+ const matches = service.findAgentsForTask('xyz abc 123')
110
+ expect(matches.every(m => m.score === 0)).toBe(true)
111
+ })
112
+
113
+ it('should sort by score descending', () => {
114
+ service.registerAgent({
115
+ name: 'FullStackDev',
116
+ description: 'Full stack developer with React expertise',
117
+ category: 'engineering',
118
+ content: 'Builds complete applications',
119
+ capabilities: ['React', 'Node.js', 'Database'],
120
+ })
121
+
122
+ const matches = service.findAgentsForTask('React frontend development')
123
+ for (let i = 1; i < matches.length; i++) {
124
+ expect(matches[i - 1].score).toBeGreaterThanOrEqual(matches[i].score)
125
+ }
126
+ })
127
+ })
128
+
129
+ describe('Task Management', () => {
130
+ it('should list all tasks sorted by creation date', async () => {
131
+ const task1 = service.createTask('FrontendDev', 'Task 1')
132
+ await new Promise(r => setTimeout(r, 100))
133
+ const task2 = service.createTask('FrontendDev', 'Task 2')
134
+ const tasks = service.listTasks()
135
+ // Verify sorted by createdAt descending (newest first)
136
+ // If timestamps are equal, order is non-deterministic, so just verify both exist
137
+ expect(tasks).toHaveLength(2)
138
+ expect(tasks.map(t => t.id)).toContain(task1.id)
139
+ expect(tasks.map(t => t.id)).toContain(task2.id)
140
+ // Verify descending order when timestamps differ
141
+ if (tasks[0].createdAt.getTime() !== tasks[1].createdAt.getTime()) {
142
+ expect(tasks[0].createdAt.getTime()).toBeGreaterThan(tasks[1].createdAt.getTime())
143
+ }
144
+ })
145
+
146
+ it('should create a task', () => {
147
+ const task = service.createTask('FrontendDev', 'Build login form', 'Auth flow v2')
148
+ expect(task.agentName).toBe('FrontendDev')
149
+ expect(task.task).toBe('Build login form')
150
+ expect(task.context).toBe('Auth flow v2')
151
+ expect(task.status).toBe('pending')
152
+ expect(task.id).toMatch(/^task_\d+_[a-z0-9]+$/)
153
+ })
154
+
155
+ it('should get task by id', () => {
156
+ const created = service.createTask('FrontendDev', 'Test task')
157
+ const retrieved = service.getTask(created.id)
158
+ expect(retrieved).toEqual(created)
159
+ })
160
+
161
+ it('should update task status', () => {
162
+ const task = service.createTask('FrontendDev', 'Test task')
163
+ const updated = service.updateTaskStatus(task.id, 'in_progress', 'Started working')
164
+ expect(updated!.status).toBe('in_progress')
165
+ expect(updated!.output).toBe('Started working')
166
+ expect(updated!.updatedAt.getTime()).toBeGreaterThanOrEqual(task.createdAt.getTime())
167
+ })
168
+
169
+ it('should return undefined when updating non-existent task', () => {
170
+ const result = service.updateTaskStatus('nonexistent', 'completed')
171
+ expect(result).toBeUndefined()
172
+ })
173
+
174
+ it('should list all tasks sorted by creation date', async () => {
175
+ const task1 = service.createTask('FrontendDev', 'Task 1')
176
+ await new Promise(r => setTimeout(r, 100))
177
+ const task2 = service.createTask('FrontendDev', 'Task 2')
178
+ const tasks = service.listTasks()
179
+ expect(tasks).toHaveLength(2)
180
+ expect(tasks.map(t => t.id)).toContain(task1.id)
181
+ expect(tasks.map(t => t.id)).toContain(task2.id)
182
+ if (tasks[0].createdAt.getTime() !== tasks[1].createdAt.getTime()) {
183
+ expect(tasks[0].createdAt.getTime()).toBeGreaterThan(tasks[1].createdAt.getTime())
184
+ }
185
+ })
186
+
187
+ it('should filter tasks by agent name', () => {
188
+ service.registerAgent(mockDesigner)
189
+ const task1 = service.createTask('FrontendDev', 'Dev task')
190
+ service.createTask('UXDesigner', 'Design task')
191
+ const devTasks = service.listTasks('frontenddev')
192
+ expect(devTasks).toHaveLength(1)
193
+ expect(devTasks[0].id).toBe(task1.id)
194
+ })
195
+
196
+ it('should filter tasks by status', () => {
197
+ const task = service.createTask('FrontendDev', 'Test task')
198
+ service.updateTaskStatus(task.id, 'completed')
199
+ const pendingTasks = service.listTasks(undefined, 'pending')
200
+ const completedTasks = service.listTasks(undefined, 'completed')
201
+ expect(pendingTasks).toHaveLength(0)
202
+ expect(completedTasks).toHaveLength(1)
203
+ })
204
+
205
+ it('should create subtask with parent reference', () => {
206
+ const parent = service.createTask('FrontendDev', 'Parent task')
207
+ const child = service.createTask('FrontendDev', 'Child task', undefined, parent.id)
208
+ const retrievedParent = service.getTask(parent.id)
209
+ expect(retrievedParent!.subtasks).toContain(child.id)
210
+ })
211
+ })
212
+
213
+ describe('Collaboration Management', () => {
214
+ beforeEach(() => {
215
+ service.registerAgent(mockAgent)
216
+ service.registerAgent(mockDesigner)
217
+ })
218
+
219
+ it('should create a collaboration', () => {
220
+ const collab = service.createCollaboration(
221
+ 'Auth Redesign',
222
+ 'Redesign authentication flow',
223
+ 'FrontendDev',
224
+ ['UXDesigner']
225
+ )
226
+ expect(collab.name).toBe('Auth Redesign')
227
+ expect(collab.leadAgent).toBe('FrontendDev')
228
+ expect(collab.participatingAgents).toContain('FrontendDev')
229
+ expect(collab.participatingAgents).toContain('UXDesigner')
230
+ expect(collab.status).toBe('planning')
231
+ })
232
+
233
+ it('should deduplicate lead agent in participants', () => {
234
+ const collab = service.createCollaboration(
235
+ 'Test',
236
+ 'Test collab',
237
+ 'FrontendDev',
238
+ ['FrontendDev', 'UXDesigner']
239
+ )
240
+ expect(collab.participatingAgents.filter(a => a === 'FrontendDev')).toHaveLength(1)
241
+ })
242
+
243
+ it('should get collaboration by id', () => {
244
+ const created = service.createCollaboration('Test', 'Test desc', 'FrontendDev', [])
245
+ const retrieved = service.getCollaboration(created.id)
246
+ expect(retrieved).toEqual(created)
247
+ })
248
+
249
+ it('should add task to collaboration', () => {
250
+ const collab = service.createCollaboration('Test', 'Test desc', 'FrontendDev', [])
251
+ const task = service.createTask('FrontendDev', 'Collab task')
252
+ service.addTaskToCollaboration(collab.id, task)
253
+ const updated = service.getCollaboration(collab.id)
254
+ expect(updated!.tasks).toContainEqual(task)
255
+ })
256
+
257
+ it('should update collaboration status', () => {
258
+ const collab = service.createCollaboration('Test', 'Test desc', 'FrontendDev', [])
259
+ service.updateCollaborationStatus(collab.id, 'active')
260
+ const updated = service.getCollaboration(collab.id)
261
+ expect(updated!.status).toBe('active')
262
+ expect(updated!.updatedAt.getTime()).toBeGreaterThanOrEqual(collab.createdAt.getTime())
263
+ })
264
+
265
+ it('should list collaborations sorted by creation date', async () => {
266
+ const collab1 = service.createCollaboration('Collab 1', 'Desc 1', 'FrontendDev', [])
267
+ await new Promise(r => setTimeout(r, 100))
268
+ const collab2 = service.createCollaboration('Collab 2', 'Desc 2', 'FrontendDev', [])
269
+ const collabs = service.listCollaborations()
270
+ expect(collabs).toHaveLength(2)
271
+ expect(collabs.map(c => c.id)).toContain(collab1.id)
272
+ expect(collabs.map(c => c.id)).toContain(collab2.id)
273
+ if (collabs[0].createdAt.getTime() !== collabs[1].createdAt.getTime()) {
274
+ expect(collabs[0].createdAt.getTime()).toBeGreaterThan(collabs[1].createdAt.getTime())
275
+ }
276
+ })
277
+
278
+ it('should filter collaborations by status', () => {
279
+ const collab = service.createCollaboration('Test', 'Test desc', 'FrontendDev', [])
280
+ service.updateCollaborationStatus(collab.id, 'active')
281
+ const planningCollabs = service.listCollaborations('planning')
282
+ const activeCollabs = service.listCollaborations('active')
283
+ expect(planningCollabs).toHaveLength(0)
284
+ expect(activeCollabs).toHaveLength(1)
285
+ })
286
+ })
287
+
288
+ describe('Messaging', () => {
289
+ it('should create a message', () => {
290
+ const msg = service.createMessage(
291
+ 'FrontendDev',
292
+ 'UXDesigner',
293
+ 'collab-123',
294
+ 'Please review the design',
295
+ 'request'
296
+ )
297
+ expect(msg.fromAgent).toBe('FrontendDev')
298
+ expect(msg.toAgent).toBe('UXDesigner')
299
+ expect(msg.collaborationId).toBe('collab-123')
300
+ expect(msg.content).toBe('Please review the design')
301
+ expect(msg.type).toBe('request')
302
+ expect(msg.id).toMatch(/^msg_\d+_[a-z0-9]+$/)
303
+ })
304
+
305
+ it('should get messages for collaboration sorted by timestamp', () => {
306
+ const collabId = 'collab-123'
307
+ service.createMessage('FrontendDev', 'UXDesigner', collabId, 'Message 1', 'request')
308
+ service.createMessage('UXDesigner', 'FrontendDev', collabId, 'Message 2', 'response')
309
+ const messages = service.getMessagesForCollaboration(collabId)
310
+ expect(messages).toHaveLength(2)
311
+ expect(messages[0].content).toBe('Message 1')
312
+ expect(messages[1].content).toBe('Message 2')
313
+ })
314
+
315
+ it('should return empty array for collaboration with no messages', () => {
316
+ const messages = service.getMessagesForCollaboration('no-messages')
317
+ expect(messages).toEqual([])
318
+ })
319
+ })
320
+
321
+ describe('Reviews', () => {
322
+ it('should create a review', () => {
323
+ const review = service.createReview(
324
+ 'task-123',
325
+ 'UXDesigner',
326
+ 'FrontendDev',
327
+ 'Great work on the implementation',
328
+ 'approved',
329
+ ['Consider adding more comments']
330
+ )
331
+ expect(review.taskId).toBe('task-123')
332
+ expect(review.reviewerAgent).toBe('UXDesigner')
333
+ expect(review.revieweeAgent).toBe('FrontendDev')
334
+ expect(review.approvalStatus).toBe('approved')
335
+ expect(review.suggestions).toEqual(['Consider adding more comments'])
336
+ expect(review.id).toMatch(/^review_\d+_[a-z0-9]+$/)
337
+ })
338
+
339
+ it('should get reviews for task sorted by creation date', async () => {
340
+ const taskId = 'task-123'
341
+ service.createReview(taskId, 'Agent1', 'Agent2', 'Review 1', 'pending')
342
+ await new Promise(r => setTimeout(r, 100))
343
+ service.createReview(taskId, 'Agent3', 'Agent2', 'Review 2', 'approved')
344
+ const reviews = service.getReviewsForTask(taskId)
345
+ expect(reviews).toHaveLength(2)
346
+ expect(reviews.map(r => r.feedback)).toContain('Review 1')
347
+ expect(reviews.map(r => r.feedback)).toContain('Review 2')
348
+ if (reviews[0].createdAt.getTime() !== reviews[1].createdAt.getTime()) {
349
+ expect(reviews[0].createdAt.getTime()).toBeGreaterThan(reviews[1].createdAt.getTime())
350
+ }
351
+ })
352
+
353
+ it('should return empty array for task with no reviews', () => {
354
+ const reviews = service.getReviewsForTask('no-reviews')
355
+ expect(reviews).toEqual([])
356
+ })
357
+ })
358
+
359
+ describe('System Prompt Generation', () => {
360
+ beforeEach(() => {
361
+ service.registerAgent(mockAgent)
362
+ })
363
+
364
+ it('should generate system prompt for agent', () => {
365
+ const prompt = service.generateSystemPrompt('FrontendDev')
366
+ expect(prompt).toContain('# FrontendDev')
367
+ expect(prompt).toContain('Frontend development specialist')
368
+ expect(prompt).toContain('Expert in React, Vue, and modern CSS')
369
+ expect(prompt).toContain('## Capabilities')
370
+ expect(prompt).toContain('- React')
371
+ })
372
+
373
+ it('should include task in system prompt', () => {
374
+ const prompt = service.generateSystemPrompt('FrontendDev', 'Build login form')
375
+ expect(prompt).toContain('## Current Task')
376
+ expect(prompt).toContain('Build login form')
377
+ })
378
+
379
+ it('should include context in system prompt', () => {
380
+ const prompt = service.generateSystemPrompt('FrontendDev', 'Build login', 'Auth flow v2')
381
+ expect(prompt).toContain('## Additional Context')
382
+ expect(prompt).toContain('Auth flow v2')
383
+ })
384
+
385
+ it('should return undefined for non-existent agent', () => {
386
+ const prompt = service.generateSystemPrompt('nonexistent')
387
+ expect(prompt).toBeUndefined()
388
+ })
389
+ })
390
+
391
+ describe('Agent Capabilities', () => {
392
+ it('should return agent capabilities', () => {
393
+ service.registerAgent(mockAgent)
394
+ const caps = service.getAgentCapabilities('FrontendDev')
395
+ expect(caps).toEqual(['React', 'Vue', 'CSS', 'TypeScript'])
396
+ })
397
+
398
+ it('should return empty array for non-existent agent', () => {
399
+ const caps = service.getAgentCapabilities('nonexistent')
400
+ expect(caps).toEqual([])
401
+ })
402
+ })
403
+
404
+ describe('Statistics', () => {
405
+ it('should return zero stats for empty service', () => {
406
+ const stats = service.getStats()
407
+ expect(stats.totalAgents).toBe(0)
408
+ expect(stats.totalTasks).toBe(0)
409
+ expect(stats.activeCollaborations).toBe(0)
410
+ expect(stats.tasksByStatus).toEqual({
411
+ pending: 0,
412
+ in_progress: 0,
413
+ completed: 0,
414
+ failed: 0,
415
+ reviewing: 0,
416
+ })
417
+ })
418
+
419
+ it('should calculate stats correctly', () => {
420
+ service.registerAgent(mockAgent)
421
+ service.registerAgent(mockDesigner)
422
+
423
+ const task1 = service.createTask('FrontendDev', 'Task 1')
424
+ service.updateTaskStatus(task1.id, 'completed')
425
+
426
+ const task2 = service.createTask('FrontendDev', 'Task 2')
427
+ service.updateTaskStatus(task2.id, 'in_progress')
428
+
429
+ service.createTask('FrontendDev', 'Task 3')
430
+
431
+ const collab = service.createCollaboration('Test', 'Desc', 'FrontendDev', [])
432
+ service.updateCollaborationStatus(collab.id, 'active')
433
+
434
+ const stats = service.getStats()
435
+ expect(stats.totalAgents).toBe(2)
436
+ expect(stats.totalTasks).toBe(3)
437
+ expect(stats.activeCollaborations).toBe(1)
438
+ expect(stats.tasksByStatus.completed).toBe(1)
439
+ expect(stats.tasksByStatus.in_progress).toBe(1)
440
+ expect(stats.tasksByStatus.pending).toBe(1)
441
+ })
442
+ })
443
+ })