crewswarm 0.8.1-beta

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 (362) hide show
  1. package/.env.example +155 -0
  2. package/LICENSE +21 -0
  3. package/README.md +316 -0
  4. package/apps/dashboard/dist/assets/chat-core-BwSoInmZ.js +1 -0
  5. package/apps/dashboard/dist/assets/chat-core-BwSoInmZ.js.br +0 -0
  6. package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js +1 -0
  7. package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js.br +0 -0
  8. package/apps/dashboard/dist/assets/components-CSUb80ze.js +1 -0
  9. package/apps/dashboard/dist/assets/components-CSUb80ze.js.br +0 -0
  10. package/apps/dashboard/dist/assets/core-utils-CAVnDoe1.js +1 -0
  11. package/apps/dashboard/dist/assets/core-utils-CAVnDoe1.js.br +0 -0
  12. package/apps/dashboard/dist/assets/index-CF0aJRtC.css +1 -0
  13. package/apps/dashboard/dist/assets/index-CF0aJRtC.css.br +0 -0
  14. package/apps/dashboard/dist/assets/index-Px49zu76.js +2 -0
  15. package/apps/dashboard/dist/assets/index-Px49zu76.js.br +0 -0
  16. package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js +1 -0
  17. package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
  18. package/apps/dashboard/dist/assets/setup-wizard-i3eEixlo.js +1 -0
  19. package/apps/dashboard/dist/assets/setup-wizard-i3eEixlo.js.br +0 -0
  20. package/apps/dashboard/dist/assets/tab-agents-tab-BThdsdJY.js +1 -0
  21. package/apps/dashboard/dist/assets/tab-agents-tab-BThdsdJY.js.br +0 -0
  22. package/apps/dashboard/dist/assets/tab-benchmarks-tab-DfCuAClu.js +1 -0
  23. package/apps/dashboard/dist/assets/tab-comms-tab-eHpOSBhG.js +1 -0
  24. package/apps/dashboard/dist/assets/tab-comms-tab-eHpOSBhG.js.br +0 -0
  25. package/apps/dashboard/dist/assets/tab-contacts-tab-yEegNyO4.js +1 -0
  26. package/apps/dashboard/dist/assets/tab-contacts-tab-yEegNyO4.js.br +0 -0
  27. package/apps/dashboard/dist/assets/tab-engines-tab-C3DYxTwy.js +1 -0
  28. package/apps/dashboard/dist/assets/tab-engines-tab-C3DYxTwy.js.br +0 -0
  29. package/apps/dashboard/dist/assets/tab-memory-tab-C59BYFQD.js +1 -0
  30. package/apps/dashboard/dist/assets/tab-memory-tab-C59BYFQD.js.br +0 -0
  31. package/apps/dashboard/dist/assets/tab-models-tab-9Ur7pXWA.js +1 -0
  32. package/apps/dashboard/dist/assets/tab-models-tab-9Ur7pXWA.js.br +0 -0
  33. package/apps/dashboard/dist/assets/tab-pm-loop-tab-D7mnDelU.js +1 -0
  34. package/apps/dashboard/dist/assets/tab-pm-loop-tab-D7mnDelU.js.br +0 -0
  35. package/apps/dashboard/dist/assets/tab-projects-tab-C6h2Mv1K.js +1 -0
  36. package/apps/dashboard/dist/assets/tab-projects-tab-C6h2Mv1K.js.br +0 -0
  37. package/apps/dashboard/dist/assets/tab-prompts-tab-C0wZvWK3.js +1 -0
  38. package/apps/dashboard/dist/assets/tab-prompts-tab-C0wZvWK3.js.br +0 -0
  39. package/apps/dashboard/dist/assets/tab-services-tab-DBj_w3bc.js +1 -0
  40. package/apps/dashboard/dist/assets/tab-services-tab-DBj_w3bc.js.br +0 -0
  41. package/apps/dashboard/dist/assets/tab-settings-tab-ezeqAjZk.js +1 -0
  42. package/apps/dashboard/dist/assets/tab-settings-tab-ezeqAjZk.js.br +0 -0
  43. package/apps/dashboard/dist/assets/tab-skills-tab-BYdU2whk.js +1 -0
  44. package/apps/dashboard/dist/assets/tab-skills-tab-BYdU2whk.js.br +0 -0
  45. package/apps/dashboard/dist/assets/tab-spending-tab-Bg6w9t_p.js +1 -0
  46. package/apps/dashboard/dist/assets/tab-spending-tab-Bg6w9t_p.js.br +0 -0
  47. package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BBV9HB2X.js +1 -0
  48. package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BBV9HB2X.js.br +0 -0
  49. package/apps/dashboard/dist/assets/tab-swarm-tab-ChqLlEVs.js +1 -0
  50. package/apps/dashboard/dist/assets/tab-swarm-tab-ChqLlEVs.js.br +0 -0
  51. package/apps/dashboard/dist/assets/tab-usage-tab-B2UWXenJ.js +1 -0
  52. package/apps/dashboard/dist/assets/tab-usage-tab-B2UWXenJ.js.br +0 -0
  53. package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js +1 -0
  54. package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
  55. package/apps/dashboard/dist/assets/tab-workflows-tab-6QSXLJ0i.js +1 -0
  56. package/apps/dashboard/dist/assets/tab-workflows-tab-6QSXLJ0i.js.br +0 -0
  57. package/apps/dashboard/dist/favicon.png +0 -0
  58. package/apps/dashboard/dist/index.html +6466 -0
  59. package/apps/dashboard/dist/index.html.br +0 -0
  60. package/apps/dashboard/dist/index.html.gz +0 -0
  61. package/apps/dashboard/dist/signup.html +446 -0
  62. package/apps/dashboard/index.html +6442 -0
  63. package/apps/dashboard/package.json +15 -0
  64. package/apps/dashboard/src/app.js +2823 -0
  65. package/apps/dashboard/src/app.js.br +0 -0
  66. package/apps/dashboard/src/app.js.gz +0 -0
  67. package/apps/dashboard/src/chat/chat-actions.js +1847 -0
  68. package/apps/dashboard/src/chat/chat-actions.js.br +0 -0
  69. package/apps/dashboard/src/chat/unified-messages.js +327 -0
  70. package/apps/dashboard/src/chat/unified-messages.js.br +0 -0
  71. package/apps/dashboard/src/cli-process.js +208 -0
  72. package/apps/dashboard/src/cli-process.js.br +0 -0
  73. package/apps/dashboard/src/cli-process.js.gz +0 -0
  74. package/apps/dashboard/src/components/active-tasks-panel.js +175 -0
  75. package/apps/dashboard/src/components/active-tasks-panel.js.br +0 -0
  76. package/apps/dashboard/src/core/api.js +18 -0
  77. package/apps/dashboard/src/core/api.js.br +0 -0
  78. package/apps/dashboard/src/core/dom.js +220 -0
  79. package/apps/dashboard/src/core/dom.js.br +0 -0
  80. package/apps/dashboard/src/core/state.js +91 -0
  81. package/apps/dashboard/src/core/state.js.br +0 -0
  82. package/apps/dashboard/src/core/task-manager.js +134 -0
  83. package/apps/dashboard/src/core/task-manager.js.br +0 -0
  84. package/apps/dashboard/src/orchestration-status.js +127 -0
  85. package/apps/dashboard/src/orchestration-status.js.br +0 -0
  86. package/apps/dashboard/src/setup-wizard.js +555 -0
  87. package/apps/dashboard/src/setup-wizard.js.br +0 -0
  88. package/apps/dashboard/src/styles.css +2085 -0
  89. package/apps/dashboard/src/styles.css.br +0 -0
  90. package/apps/dashboard/src/styles.css.gz +0 -0
  91. package/apps/dashboard/src/tabs/agents-tab.js +2237 -0
  92. package/apps/dashboard/src/tabs/agents-tab.js.br +0 -0
  93. package/apps/dashboard/src/tabs/benchmarks-tab.js +229 -0
  94. package/apps/dashboard/src/tabs/benchmarks-tab.js.br +0 -0
  95. package/apps/dashboard/src/tabs/comms-tab.js +955 -0
  96. package/apps/dashboard/src/tabs/comms-tab.js.br +0 -0
  97. package/apps/dashboard/src/tabs/contacts-tab.js +654 -0
  98. package/apps/dashboard/src/tabs/contacts-tab.js.br +0 -0
  99. package/apps/dashboard/src/tabs/engines-tab.js +175 -0
  100. package/apps/dashboard/src/tabs/engines-tab.js.br +0 -0
  101. package/apps/dashboard/src/tabs/memory-tab.js +182 -0
  102. package/apps/dashboard/src/tabs/memory-tab.js.br +0 -0
  103. package/apps/dashboard/src/tabs/models-tab.js +441 -0
  104. package/apps/dashboard/src/tabs/models-tab.js.br +0 -0
  105. package/apps/dashboard/src/tabs/pm-loop-tab.js +185 -0
  106. package/apps/dashboard/src/tabs/pm-loop-tab.js.br +0 -0
  107. package/apps/dashboard/src/tabs/projects-tab.js +663 -0
  108. package/apps/dashboard/src/tabs/projects-tab.js.br +0 -0
  109. package/apps/dashboard/src/tabs/projects-tab.js.gz +0 -0
  110. package/apps/dashboard/src/tabs/prompts-tab.js +160 -0
  111. package/apps/dashboard/src/tabs/prompts-tab.js.br +0 -0
  112. package/apps/dashboard/src/tabs/services-tab.js +202 -0
  113. package/apps/dashboard/src/tabs/services-tab.js.br +0 -0
  114. package/apps/dashboard/src/tabs/settings-tab.js +803 -0
  115. package/apps/dashboard/src/tabs/settings-tab.js.br +0 -0
  116. package/apps/dashboard/src/tabs/skills-tab.js +284 -0
  117. package/apps/dashboard/src/tabs/skills-tab.js.br +0 -0
  118. package/apps/dashboard/src/tabs/spending-tab.js +173 -0
  119. package/apps/dashboard/src/tabs/spending-tab.js.br +0 -0
  120. package/apps/dashboard/src/tabs/swarm-chat-tab.js +660 -0
  121. package/apps/dashboard/src/tabs/swarm-chat-tab.js.br +0 -0
  122. package/apps/dashboard/src/tabs/swarm-tab.js +538 -0
  123. package/apps/dashboard/src/tabs/swarm-tab.js.br +0 -0
  124. package/apps/dashboard/src/tabs/usage-tab.js +390 -0
  125. package/apps/dashboard/src/tabs/usage-tab.js.br +0 -0
  126. package/apps/dashboard/src/tabs/waves-tab.js +238 -0
  127. package/apps/dashboard/src/tabs/waves-tab.js.br +0 -0
  128. package/apps/dashboard/src/tabs/workflows-tab.js +747 -0
  129. package/apps/dashboard/src/tabs/workflows-tab.js.br +0 -0
  130. package/apps/vibe/.crew/agent-memory/pipeline.json +249 -0
  131. package/apps/vibe/.crew/cost.json +17 -0
  132. package/apps/vibe/.crew/json-parse-metrics.jsonl +22 -0
  133. package/apps/vibe/.crew/pipeline-metrics.jsonl +22 -0
  134. package/apps/vibe/.crew/pipeline-runs/pipeline-0f90c392-2425-4ae5-850c-bd9d17b1d690.jsonl +5 -0
  135. package/apps/vibe/.crew/pipeline-runs/pipeline-1c269dd9-a63f-4fba-af81-5cf08048ef06.jsonl +5 -0
  136. package/apps/vibe/.crew/pipeline-runs/pipeline-288a7765-da24-4a22-89bc-1f3cc9b0562c.jsonl +1 -0
  137. package/apps/vibe/.crew/pipeline-runs/pipeline-2c78fd22-a657-4bd1-bc49-0679fb384409.jsonl +5 -0
  138. package/apps/vibe/.crew/pipeline-runs/pipeline-3e6fe08d-3264-404a-8df3-aab7efef10e7.jsonl +5 -0
  139. package/apps/vibe/.crew/pipeline-runs/pipeline-42eec610-57fe-4e09-9e7e-b315038495c2.jsonl +5 -0
  140. package/apps/vibe/.crew/pipeline-runs/pipeline-4438eb4c-ae13-42b1-90e2-b043d8983be8.jsonl +5 -0
  141. package/apps/vibe/.crew/pipeline-runs/pipeline-4740a9f5-86e7-44b6-a394-de433e291727.jsonl +5 -0
  142. package/apps/vibe/.crew/pipeline-runs/pipeline-49e1da6a-957e-48fd-9220-415019e4f8e2.jsonl +5 -0
  143. package/apps/vibe/.crew/pipeline-runs/pipeline-4c9251db-be68-427b-a3fc-a264f2b5778d.jsonl +5 -0
  144. package/apps/vibe/.crew/pipeline-runs/pipeline-65e29a57-664d-4196-8109-017e364f182e.jsonl +5 -0
  145. package/apps/vibe/.crew/pipeline-runs/pipeline-6aa04bc5-9593-4b1f-b58d-3bf2978cb602.jsonl +5 -0
  146. package/apps/vibe/.crew/pipeline-runs/pipeline-6e1cba53-9b70-457e-99e0-59199149dd21.jsonl +5 -0
  147. package/apps/vibe/.crew/pipeline-runs/pipeline-749f41cc-4dac-4204-be64-873a6080a0d2.jsonl +5 -0
  148. package/apps/vibe/.crew/pipeline-runs/pipeline-74d68121-e181-4864-bd9a-c3211341dfaf.jsonl +5 -0
  149. package/apps/vibe/.crew/pipeline-runs/pipeline-8509bc24-142d-4e07-b44a-a50bf99d1103.jsonl +5 -0
  150. package/apps/vibe/.crew/pipeline-runs/pipeline-960339c6-07ca-43ce-9900-f6e1702b39b9.jsonl +5 -0
  151. package/apps/vibe/.crew/pipeline-runs/pipeline-9c6480a9-7031-4146-b241-825b9a2d1de1.jsonl +5 -0
  152. package/apps/vibe/.crew/pipeline-runs/pipeline-9fd42426-8492-4157-9d5f-e1537c060489.jsonl +2 -0
  153. package/apps/vibe/.crew/pipeline-runs/pipeline-ad6d40a3-2f5e-46a9-a345-47caaccc51aa.jsonl +5 -0
  154. package/apps/vibe/.crew/pipeline-runs/pipeline-bc606133-8d5b-4535-8d85-f1a29cdaa981.jsonl +5 -0
  155. package/apps/vibe/.crew/pipeline-runs/pipeline-c1a13ccd-634a-4d01-a4a7-1177b8a752ff.jsonl +5 -0
  156. package/apps/vibe/.crew/pipeline-runs/pipeline-c7d27b42-249e-4bd4-8f26-6aa998110b8a.jsonl +5 -0
  157. package/apps/vibe/.crew/pipeline-runs/pipeline-cca2e9b9-4a34-4d25-a311-5c793fa7e91e.jsonl +5 -0
  158. package/apps/vibe/.crew/sandbox.json +7 -0
  159. package/apps/vibe/.crew/session.json +285 -0
  160. package/apps/vibe/.crew/training-data.jsonl +0 -0
  161. package/apps/vibe/.github/workflows/studio-quality.yml +37 -0
  162. package/apps/vibe/.studio-data/project-messages/chuck-norris.jsonl +12 -0
  163. package/apps/vibe/.studio-data/project-messages/general.jsonl +54 -0
  164. package/apps/vibe/.studio-data/project-messages/studio-local.jsonl +10 -0
  165. package/apps/vibe/ARCHITECTURE.md +3393 -0
  166. package/apps/vibe/QUICK-REFERENCE.md +211 -0
  167. package/apps/vibe/README.md +76 -0
  168. package/apps/vibe/ROADMAP.md +41 -0
  169. package/apps/vibe/STUDIO-SETUP-COMPLETE.md +35 -0
  170. package/apps/vibe/VISUAL-GUIDE.md +378 -0
  171. package/apps/vibe/capture-demo.mjs +160 -0
  172. package/apps/vibe/capture-vibe-assets.mjs +71 -0
  173. package/apps/vibe/capture-vibe-video.mjs +260 -0
  174. package/apps/vibe/check-buttons.js +41 -0
  175. package/apps/vibe/diagnose.html +106 -0
  176. package/apps/vibe/fix-buttons.js +103 -0
  177. package/apps/vibe/index.html +3401 -0
  178. package/apps/vibe/package-lock.json +920 -0
  179. package/apps/vibe/package.json +31 -0
  180. package/apps/vibe/public/favicon.png +0 -0
  181. package/apps/vibe/scripts/studio-pty-host.py +117 -0
  182. package/apps/vibe/server.mjs +1835 -0
  183. package/apps/vibe/src/main.js +2846 -0
  184. package/apps/vibe/src/register-all-languages.js +98 -0
  185. package/apps/vibe/start-studio.sh +11 -0
  186. package/apps/vibe/test/accessibility-tests.js +77 -0
  187. package/apps/vibe/test/browser-performance-audit.mjs +205 -0
  188. package/apps/vibe/test/performance-tests.js +120 -0
  189. package/apps/vibe/test/security-tests.js +213 -0
  190. package/apps/vibe/tests/e2e.local.mjs +54 -0
  191. package/apps/vibe/tests/server.smoke.mjs +106 -0
  192. package/apps/vibe/update_website.mjs +74 -0
  193. package/apps/vibe/vite.config.js +19 -0
  194. package/apps/vibe/watch-server.mjs +108 -0
  195. package/contrib/openclaw-plugin/README.md +199 -0
  196. package/contrib/openclaw-plugin/index.ts +306 -0
  197. package/contrib/openclaw-plugin/openclaw.plugin.json +41 -0
  198. package/contrib/openclaw-plugin/package.json +27 -0
  199. package/contrib/openclaw-plugin/skills/crewswarm/SKILL.md +88 -0
  200. package/crew-lead.mjs +649 -0
  201. package/engines/claude-code.json +36 -0
  202. package/engines/codex.json +37 -0
  203. package/engines/crew-cli.json +42 -0
  204. package/engines/cursor.json +40 -0
  205. package/engines/docker-sandbox.json +38 -0
  206. package/engines/gemini-cli.json +75 -0
  207. package/engines/opencode.json +31 -0
  208. package/gateway-bridge.mjs +1575 -0
  209. package/install.sh +738 -0
  210. package/lib/agent-registry.mjs +232 -0
  211. package/lib/agents/daemon.mjs +121 -0
  212. package/lib/agents/dispatch.mjs +225 -0
  213. package/lib/agents/permissions.mjs +90 -0
  214. package/lib/agents/platform-formatting.mjs +102 -0
  215. package/lib/agents/registry.mjs +81 -0
  216. package/lib/agents/tool-instructions.mjs +257 -0
  217. package/lib/agents/validation.mjs +75 -0
  218. package/lib/approval/policy-manager.mjs +221 -0
  219. package/lib/autoharness/index.mjs +391 -0
  220. package/lib/bridges/cli-executor.mjs +332 -0
  221. package/lib/bridges/gateway-ws.mjs +345 -0
  222. package/lib/bridges/integration.mjs +229 -0
  223. package/lib/bridges/rag-helper.mjs +90 -0
  224. package/lib/browser/opencode-passthrough-filter.js +44 -0
  225. package/lib/browser/passthrough-stderr.js +109 -0
  226. package/lib/chat/autonomous-mentions.mjs +373 -0
  227. package/lib/chat/history.mjs +82 -0
  228. package/lib/chat/mention-routing-intent.mjs +136 -0
  229. package/lib/chat/participants.mjs +95 -0
  230. package/lib/chat/project-messages-rag.mjs +265 -0
  231. package/lib/chat/project-messages.mjs +479 -0
  232. package/lib/chat/shared-chat-prompt-overlay.mjs +52 -0
  233. package/lib/chat/thread-binding.mjs +34 -0
  234. package/lib/chat/unified-history.mjs +223 -0
  235. package/lib/chat/unified-wrapper.mjs +41 -0
  236. package/lib/cli-process-tracker.mjs +228 -0
  237. package/lib/collections/index.mjs +433 -0
  238. package/lib/contacts/identity-linker.mjs +248 -0
  239. package/lib/contacts/index.mjs +341 -0
  240. package/lib/crew-judge/PROMPT.md +93 -0
  241. package/lib/crew-judge/judge.mjs +260 -0
  242. package/lib/crew-lead/agent-manager.mjs +125 -0
  243. package/lib/crew-lead/background.mjs +270 -0
  244. package/lib/crew-lead/brain.mjs +110 -0
  245. package/lib/crew-lead/chat-handler.mjs +2603 -0
  246. package/lib/crew-lead/chat-handler.mjs.bak +1274 -0
  247. package/lib/crew-lead/classifier.mjs +83 -0
  248. package/lib/crew-lead/http-server.mjs +4824 -0
  249. package/lib/crew-lead/intent.mjs +102 -0
  250. package/lib/crew-lead/interval-manager.mjs +41 -0
  251. package/lib/crew-lead/llm-caller.mjs +544 -0
  252. package/lib/crew-lead/prompts.mjs +392 -0
  253. package/lib/crew-lead/retry-manager.mjs +118 -0
  254. package/lib/crew-lead/tools.mjs +318 -0
  255. package/lib/crew-lead/wave-dispatcher.mjs +798 -0
  256. package/lib/crew-lead/waves-config.json +73 -0
  257. package/lib/crew-lead/waves-loader.mjs +110 -0
  258. package/lib/crew-lead/ws-router.mjs +428 -0
  259. package/lib/dispatch/parsers.mjs +299 -0
  260. package/lib/domain-planning/detector.mjs +196 -0
  261. package/lib/domain-planning/prompts/crew-pm-cli.md +96 -0
  262. package/lib/domain-planning/prompts/crew-pm-core.md +122 -0
  263. package/lib/domain-planning/prompts/crew-pm-frontend.md +111 -0
  264. package/lib/engines/crew-cli-sandbox.mjs +422 -0
  265. package/lib/engines/crew-cli.mjs +155 -0
  266. package/lib/engines/cursor-launcher.mjs +110 -0
  267. package/lib/engines/engine-registry.mjs +253 -0
  268. package/lib/engines/llm-direct.mjs +184 -0
  269. package/lib/engines/opencode.mjs +256 -0
  270. package/lib/engines/ouroboros.mjs +114 -0
  271. package/lib/engines/rt-envelope.mjs +1643 -0
  272. package/lib/engines/rt-envelope.mjs.backup-current +870 -0
  273. package/lib/engines/runners.mjs +1367 -0
  274. package/lib/gemini-cli-passthrough-noise.mjs +37 -0
  275. package/lib/integrations/code-search.mjs +259 -0
  276. package/lib/integrations/greptile.mjs +148 -0
  277. package/lib/integrations/multimodal.mjs +313 -0
  278. package/lib/integrations/telegram-streaming.mjs +153 -0
  279. package/lib/integrations/tts.mjs +312 -0
  280. package/lib/integrations/twitter-links.mjs +294 -0
  281. package/lib/memory/shared-adapter.mjs +296 -0
  282. package/lib/pipeline/manager.mjs +539 -0
  283. package/lib/preferences/extractor.mjs +347 -0
  284. package/lib/project-dir.mjs +20 -0
  285. package/lib/runtime/config.mjs +388 -0
  286. package/lib/runtime/dlq.mjs +170 -0
  287. package/lib/runtime/log-rotation.mjs +82 -0
  288. package/lib/runtime/logger.mjs +58 -0
  289. package/lib/runtime/memory.mjs +421 -0
  290. package/lib/runtime/paths.mjs +76 -0
  291. package/lib/runtime/project-dir.mjs +127 -0
  292. package/lib/runtime/spending.mjs +204 -0
  293. package/lib/runtime/startup-guard.mjs +291 -0
  294. package/lib/runtime/task-lease.mjs +234 -0
  295. package/lib/runtime/telemetry-schema.mjs +208 -0
  296. package/lib/runtime/telemetry.mjs +101 -0
  297. package/lib/runtime/utils.mjs +64 -0
  298. package/lib/skills/index.mjs +265 -0
  299. package/lib/tools/browser.mjs +135 -0
  300. package/lib/tools/executor.mjs +913 -0
  301. package/lib/types.d.ts +57 -0
  302. package/package.json +106 -0
  303. package/pm-loop.mjs +1626 -0
  304. package/prompts/coder-back.md +27 -0
  305. package/prompts/coder-front.md +27 -0
  306. package/prompts/coder.md +28 -0
  307. package/prompts/copywriter.md +17 -0
  308. package/prompts/fixer.md +39 -0
  309. package/prompts/frontend.md +23 -0
  310. package/prompts/github.md +24 -0
  311. package/prompts/main.md +39 -0
  312. package/prompts/pm-cli.md +95 -0
  313. package/prompts/pm-core.md +121 -0
  314. package/prompts/pm-frontend.md +110 -0
  315. package/prompts/pm.md +234 -0
  316. package/prompts/qa.md +44 -0
  317. package/prompts/security.md +19 -0
  318. package/scripts/build-crew-chat.sh +28 -0
  319. package/scripts/build-llms-full.mjs +52 -0
  320. package/scripts/chatmock-login.sh +16 -0
  321. package/scripts/chatmock-serve.sh +16 -0
  322. package/scripts/check-dashboard.mjs +88 -0
  323. package/scripts/crew-scribe.mjs +326 -0
  324. package/scripts/dashboard-helpers.mjs +391 -0
  325. package/scripts/dashboard-validation.mjs +198 -0
  326. package/scripts/dashboard.mjs +9717 -0
  327. package/scripts/dlq-replay.mjs +61 -0
  328. package/scripts/doctor.mjs +196 -0
  329. package/scripts/file-lock.mjs +186 -0
  330. package/scripts/fresh-machine-smoke.sh +323 -0
  331. package/scripts/generate-changelog.mjs +227 -0
  332. package/scripts/generate-openapi.mjs +334 -0
  333. package/scripts/health-check.mjs +229 -0
  334. package/scripts/install-docker.sh +213 -0
  335. package/scripts/mcp-server.mjs +1625 -0
  336. package/scripts/opencrew-rt-daemon.mjs +568 -0
  337. package/scripts/openswitchctl +646 -0
  338. package/scripts/refactor-configs.mjs +39 -0
  339. package/scripts/release-check.sh +46 -0
  340. package/scripts/resolve-node-bin.sh +25 -0
  341. package/scripts/restart-all-from-repo.sh +329 -0
  342. package/scripts/restart-crew-lead.sh +98 -0
  343. package/scripts/restart-dashboard.sh +104 -0
  344. package/scripts/restart-service.sh +274 -0
  345. package/scripts/run-accessibility-audit.mjs +356 -0
  346. package/scripts/run-integration-bounded.mjs +188 -0
  347. package/scripts/run-scheduled-pipeline.mjs +230 -0
  348. package/scripts/run.mjs +41 -0
  349. package/scripts/scan-skills.mjs +79 -0
  350. package/scripts/setup-firewall.sh +128 -0
  351. package/scripts/smoke-dispatch.mjs +149 -0
  352. package/scripts/smoke.sh +163 -0
  353. package/scripts/start-crew.mjs +328 -0
  354. package/scripts/start.mjs +146 -0
  355. package/scripts/swiftbar-restart-service.sh +19 -0
  356. package/scripts/sync-agents.mjs +152 -0
  357. package/scripts/sync-prompts.mjs +79 -0
  358. package/scripts/validate-config.mjs +337 -0
  359. package/scripts/wow.mjs +89 -0
  360. package/telegram-bridge.mjs +2421 -0
  361. package/unified-orchestrator.mjs +519 -0
  362. package/whatsapp-bridge.mjs +1481 -0
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate complete OpenAPI spec from actual endpoint implementations
4
+ */
5
+
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const rootDir = path.resolve(__dirname, "..");
12
+
13
+ // Read the old spec to preserve schemas
14
+ const oldSpecPath = path.join(rootDir, "crew-cli/docs/openapi.unified.v1.json");
15
+ const oldSpec = JSON.parse(fs.readFileSync(oldSpecPath, "utf8"));
16
+
17
+ const spec = {
18
+ openapi: "3.1.0",
19
+ info: {
20
+ title: "crewswarm Complete API",
21
+ version: "2.0.0",
22
+ description: "Complete API specification for crewswarm Dashboard (port 4319) and crew-lead (port 5010). Includes all agent orchestration, messaging integrations, memory management, and system control endpoints."
23
+ },
24
+ servers: [
25
+ {
26
+ url: "http://127.0.0.1:4319",
27
+ description: "Dashboard API (primary web interface)"
28
+ },
29
+ {
30
+ url: "http://127.0.0.1:5010",
31
+ description: "crew-lead API (orchestration and chat)"
32
+ }
33
+ ],
34
+ tags: [
35
+ { name: "Core", description: "Essential system endpoints" },
36
+ { name: "Agents", description: "Agent management and configuration" },
37
+ { name: "Chat", description: "Conversational interfaces" },
38
+ { name: "Dispatch", description: "Task dispatch and orchestration" },
39
+ { name: "Projects", description: "Project and roadmap management" },
40
+ { name: "PM Loop", description: "Project manager autonomous loop" },
41
+ { name: "Build", description: "Build orchestration" },
42
+ { name: "Providers", description: "LLM provider configuration" },
43
+ { name: "Skills", description: "Skill plugin management" },
44
+ { name: "Memory", description: "Shared memory and brain" },
45
+ { name: "Messaging", description: "Telegram and WhatsApp integrations" },
46
+ { name: "Contacts", description: "Contact management" },
47
+ { name: "Settings", description: "System configuration" },
48
+ { name: "Services", description: "Service lifecycle management" },
49
+ { name: "Engines", description: "Engine passthrough and configuration" },
50
+ { name: "Multimodal", description: "Image and audio processing" },
51
+ { name: "Telemetry", description: "Usage tracking and spending" }
52
+ ],
53
+ paths: {},
54
+ components: oldSpec.components // Preserve existing schemas
55
+ };
56
+
57
+ // Dashboard endpoints with methods and tags
58
+ const dashboardEndpoints = {
59
+ "/": { get: "Core" },
60
+ "/health": { get: "Core" },
61
+ "/api/health": { get: "Core" },
62
+ "/api/agents": { get: "Agents" },
63
+ "/api/agents-config": { get: "Agents" },
64
+ "/api/agents-config/create": { post: "Agents" },
65
+ "/api/agents-config/update": { post: "Agents" },
66
+ "/api/agents-config/delete": { post: "Agents" },
67
+ "/api/agents-config/reset-session": { post: "Agents" },
68
+ "/api/agents/reset-session": { post: "Agents" },
69
+ "/api/crew-lead/chat": { post: "Chat" },
70
+ "/api/crew-lead/history": { get: "Chat" },
71
+ "/api/crew-lead/clear": { post: "Chat" },
72
+ "/api/crew-lead/status": { get: "Chat" },
73
+ "/api/crew-lead/events": { get: "Chat" },
74
+ "/api/crew-lead/confirm-project": { post: "Projects" },
75
+ "/api/crew-lead/discard-project": { post: "Projects" },
76
+ "/api/dispatch": { post: "Dispatch" },
77
+ "/api/projects": { get: "Projects", post: "Projects" },
78
+ "/api/projects/update": { post: "Projects" },
79
+ "/api/projects/delete": { post: "Projects" },
80
+ "/api/pm-loop/start": { post: "PM Loop" },
81
+ "/api/pm-loop/stop": { post: "PM Loop" },
82
+ "/api/pm-loop/status": { get: "PM Loop" },
83
+ "/api/pm-loop/log": { get: "PM Loop" },
84
+ "/api/pm-loop/roadmap": { get: "PM Loop" },
85
+ "/api/roadmap/read": { post: "PM Loop" },
86
+ "/api/roadmap/write": { post: "PM Loop" },
87
+ "/api/roadmap/retry-failed": { post: "PM Loop" },
88
+ "/api/build": { post: "Build" },
89
+ "/api/build/stop": { post: "Build" },
90
+ "/api/continuous-build": { post: "Build" },
91
+ "/api/continuous-build/stop": { post: "Build" },
92
+ "/api/continuous-build/log": { get: "Build" },
93
+ "/api/phased-progress": { get: "Build" },
94
+ "/api/providers": { get: "Providers" },
95
+ "/api/providers/builtin": { get: "Providers" },
96
+ "/api/providers/builtin/save": { post: "Providers" },
97
+ "/api/providers/builtin/test": { post: "Providers" },
98
+ "/api/providers/add": { post: "Providers" },
99
+ "/api/providers/save": { post: "Providers" },
100
+ "/api/providers/test": { post: "Providers" },
101
+ "/api/providers/fetch-models": { post: "Providers" },
102
+ "/api/skills/import": { post: "Skills" },
103
+ "/api/memory/stats": { get: "Memory" },
104
+ "/api/memory/search": { post: "Memory" },
105
+ "/api/memory/migrate": { post: "Memory" },
106
+ "/api/memory/compact": { post: "Memory" },
107
+ "/api/telegram/config": { get: "Messaging", post: "Messaging" },
108
+ "/api/telegram/start": { post: "Messaging" },
109
+ "/api/telegram/stop": { post: "Messaging" },
110
+ "/api/telegram/status": { get: "Messaging" },
111
+ "/api/telegram/messages": { get: "Messaging" },
112
+ "/api/telegram/discover-topics": { get: "Messaging" },
113
+ "/api/telegram-sessions": { get: "Messaging" },
114
+ "/api/whatsapp/config": { get: "Messaging", post: "Messaging" },
115
+ "/api/whatsapp/start": { post: "Messaging" },
116
+ "/api/whatsapp/stop": { post: "Messaging" },
117
+ "/api/whatsapp/status": { get: "Messaging" },
118
+ "/api/whatsapp/messages": { get: "Messaging" },
119
+ "/api/contacts": { get: "Contacts" },
120
+ "/api/contacts/update": { post: "Contacts" },
121
+ "/api/contacts/delete": { post: "Contacts" },
122
+ "/api/contacts/send": { post: "Contacts" },
123
+ "/api/settings/rt-token": { get: "Settings", post: "Settings" },
124
+ "/api/settings/opencode-project": { get: "Settings", post: "Settings" },
125
+ "/api/settings/bg-consciousness": { get: "Settings", post: "Settings" },
126
+ "/api/settings/cursor-waves": { get: "Settings", post: "Settings" },
127
+ "/api/settings/claude-code": { get: "Settings", post: "Settings" },
128
+ "/api/settings/codex": { get: "Settings", post: "Settings" },
129
+ "/api/settings/gemini-cli": { get: "Settings", post: "Settings" },
130
+ "/api/settings/crew-cli": { get: "Settings", post: "Settings" },
131
+ "/api/settings/global-fallback": { get: "Settings", post: "Settings" },
132
+ "/api/settings/global-oc-loop": { get: "Settings", post: "Settings" },
133
+ "/api/settings/global-rules": { get: "Settings", post: "Settings" },
134
+ "/api/settings/loop-brain": { get: "Settings", post: "Settings" },
135
+ "/api/settings/openclaw-status": { get: "Settings" },
136
+ "/api/settings/passthrough-notify": { get: "Settings", post: "Settings" },
137
+ "/api/settings/role-defaults": { get: "Settings", post: "Settings" },
138
+ "/api/settings/spending-caps": { get: "Settings", post: "Settings" },
139
+ "/api/env": { get: "Settings" },
140
+ "/api/env-advanced": { get: "Settings", post: "Settings" },
141
+ "/api/services/status": { get: "Services" },
142
+ "/api/services/restart": { post: "Services" },
143
+ "/api/services/stop": { post: "Services" },
144
+ "/api/crew/start": { post: "Services" },
145
+ "/api/engines": { get: "Engines" },
146
+ "/api/engines/import": { post: "Engines" },
147
+ "/api/engine-passthrough": { post: "Engines" },
148
+ "/api/opencode-models": { get: "Engines" },
149
+ "/api/opencode-stats": { get: "Engines" },
150
+ "/api/passthrough-sessions": { get: "Engines", delete: "Engines" },
151
+ "/api/analyze-image": { post: "Multimodal" },
152
+ "/api/transcribe-audio": { post: "Multimodal" },
153
+ "/api/token-usage": { get: "Telemetry" },
154
+ "/api/dlq": { get: "Core" },
155
+ "/api/dlq/replay": { post: "Core" },
156
+ "/api/waves/config": { get: "Core", post: "Core" },
157
+ "/api/waves/config/reset": { post: "Core" },
158
+ "/api/prompts": { get: "Core", post: "Core" },
159
+ "/api/cmd-allowlist": { get: "Core", post: "Core", delete: "Core" },
160
+ "/api/cmd-approve": { post: "Core" },
161
+ "/api/cmd-reject": { post: "Core" },
162
+ "/api/enhance-prompt": { post: "Core" },
163
+ "/api/search-tools": { get: "Core" },
164
+ "/api/search-tools/save": { post: "Core" },
165
+ "/api/search-tools/test": { post: "Core" },
166
+ "/api/benchmark-tasks": { get: "Core" },
167
+ "/api/benchmark-run": { post: "Core" },
168
+ "/api/files": { get: "Core" },
169
+ "/api/file-content": { get: "Core" },
170
+ "/api/pick-folder": { get: "Core" },
171
+ "/api/sessions": { get: "Core" },
172
+ "/api/messages": { get: "Core" },
173
+ "/api/send": { post: "Core" },
174
+ "/api/rt-messages": { get: "Core" }
175
+ };
176
+
177
+ // crew-lead endpoints
178
+ const crewLeadEndpoints = {
179
+ "/health": { get: "Core" },
180
+ "/status": { get: "Core" },
181
+ "/chat": { post: "Chat" },
182
+ "/history": { get: "Chat" },
183
+ "/clear": { post: "Chat" },
184
+ "/events": { get: "Chat" },
185
+ "/confirm-project": { post: "Projects" },
186
+ "/discard-project": { post: "Projects" },
187
+ "/api/dispatch": { post: "Dispatch" },
188
+ "/api/classify": { post: "Dispatch" },
189
+ "/api/chat-agent": { post: "Dispatch" },
190
+ "/api/agents": { get: "Agents" },
191
+ "/api/agents/opencode": { get: "Agents" },
192
+ "/api/skills": { get: "Skills", post: "Skills" },
193
+ "/api/skills/approve": { post: "Skills" },
194
+ "/api/skills/reject": { post: "Skills" },
195
+ "/api/crew-lead/history": { get: "Chat" },
196
+ "/api/engine-passthrough": { post: "Engines" },
197
+ "/api/opencode-event": { post: "Engines" },
198
+ "/api/opencode-sessions": { get: "Engines" },
199
+ "/api/claude-sessions": { get: "Engines" },
200
+ "/api/passthrough-sessions": { get: "Engines" },
201
+ "/api/services/health": { get: "Services" },
202
+ "/api/services/restart-opencode": { post: "Services" },
203
+ "/api/settings/bg-consciousness": { get: "Settings", post: "Settings" },
204
+ "/api/settings/claude-code": { get: "Settings", post: "Settings" },
205
+ "/api/settings/cursor-waves": { get: "Settings", post: "Settings" },
206
+ "/api/settings/global-fallback": { get: "Settings", post: "Settings" },
207
+ "/api/settings/opencode-project": { get: "Settings", post: "Settings" },
208
+ "/api/spending": { get: "Telemetry" },
209
+ "/api/spending/reset": { post: "Telemetry" },
210
+ "/api/telemetry": { get: "Telemetry" },
211
+ "/api/agent-transcripts/recent": { get: "Telemetry" },
212
+ "/api/background": { get: "Core" },
213
+ "/api/health": { get: "Core" },
214
+ "/allowlist-cmd": { get: "Core", post: "Core", delete: "Core" },
215
+ "/approve-cmd": { post: "Core" },
216
+ "/reject-cmd": { post: "Core" }
217
+ };
218
+
219
+ // Generate path objects
220
+ function createPathObject(path, methods, tag) {
221
+ const pathObj = {};
222
+ const methodList = typeof methods === "string" ? [methods] : methods;
223
+
224
+ for (const method of methodList) {
225
+ pathObj[method] = {
226
+ tags: [tag],
227
+ summary: `${method.toUpperCase()} ${path}`,
228
+ responses: {
229
+ "200": {
230
+ description: "Success",
231
+ content: {
232
+ "application/json": {
233
+ schema: { type: "object" }
234
+ }
235
+ }
236
+ }
237
+ }
238
+ };
239
+
240
+ // Add request body for POST/PUT/PATCH
241
+ if (["post", "put", "patch"].includes(method)) {
242
+ pathObj[method].requestBody = {
243
+ content: {
244
+ "application/json": {
245
+ "schema": { type: "object" }
246
+ }
247
+ }
248
+ };
249
+ }
250
+ }
251
+
252
+ return pathObj;
253
+ }
254
+
255
+ // Merge dashboard endpoints
256
+ for (const [path, methodsOrObj] of Object.entries(dashboardEndpoints)) {
257
+ if (typeof methodsOrObj === "object" && !Array.isArray(methodsOrObj)) {
258
+ const methods = Object.keys(methodsOrObj);
259
+ const tags = Object.values(methodsOrObj);
260
+ spec.paths[path] = {};
261
+ for (let i = 0; i < methods.length; i++) {
262
+ spec.paths[path][methods[i]] = {
263
+ tags: [tags[i]],
264
+ summary: `${methods[i].toUpperCase()} ${path}`,
265
+ responses: {
266
+ "200": {
267
+ description: "Success",
268
+ content: {
269
+ "application/json": {
270
+ schema: { type: "object" }
271
+ }
272
+ }
273
+ }
274
+ }
275
+ };
276
+ if (["post", "put", "patch"].includes(methods[i])) {
277
+ spec.paths[path][methods[i]].requestBody = {
278
+ content: {
279
+ "application/json": {
280
+ schema: { type: "object" }
281
+ }
282
+ }
283
+ };
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ // Merge crew-lead endpoints
290
+ for (const [path, methodsOrObj] of Object.entries(crewLeadEndpoints)) {
291
+ if (!spec.paths[path]) {
292
+ spec.paths[path] = {};
293
+ }
294
+ if (typeof methodsOrObj === "object" && !Array.isArray(methodsOrObj)) {
295
+ const methods = Object.keys(methodsOrObj);
296
+ const tags = Object.values(methodsOrObj);
297
+ for (let i = 0; i < methods.length; i++) {
298
+ if (!spec.paths[path][methods[i]]) {
299
+ spec.paths[path][methods[i]] = {
300
+ tags: [tags[i]],
301
+ summary: `${methods[i].toUpperCase()} ${path}`,
302
+ responses: {
303
+ "200": {
304
+ description: "Success",
305
+ content: {
306
+ "application/json": {
307
+ schema: { type: "object" }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ };
313
+ if (["post", "put", "patch"].includes(methods[i])) {
314
+ spec.paths[path][methods[i]].requestBody = {
315
+ content: {
316
+ "application/json": {
317
+ schema: { type: "object" }
318
+ }
319
+ }
320
+ };
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+
327
+ // Write output
328
+ const outputPath = path.join(rootDir, "crew-cli/docs/openapi.complete.v2.json");
329
+ fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf8");
330
+
331
+ console.log(`✅ Generated complete OpenAPI spec:`);
332
+ console.log(` ${outputPath}`);
333
+ console.log(` ${Object.keys(spec.paths).length} endpoints documented`);
334
+ console.log(` ${spec.tags.length} tag categories`);
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * crewswarm Health Check
4
+ *
5
+ * Fast all-systems status — completes in < 10 seconds.
6
+ * Checks every service, CLI tool, API key, and MCP server.
7
+ *
8
+ * Usage:
9
+ * node scripts/health-check.mjs # full check
10
+ * node scripts/health-check.mjs --json # machine-readable output
11
+ * node scripts/health-check.mjs --quiet # only print failures
12
+ * node scripts/health-check.mjs --no-services # skip live service/agent/chat checks (CI static mode)
13
+ */
14
+
15
+ import fs from "node:fs";
16
+ import path from "node:path";
17
+ import os from "node:os";
18
+ import { execSync } from "node:child_process";
19
+
20
+ const JSON_MODE = process.argv.includes("--json");
21
+ const QUIET_MODE = process.argv.includes("--quiet");
22
+ const NO_SERVICES = process.argv.includes("--no-services"); // skip live checks for CI static mode
23
+ const CREW_LEAD = process.env.CREW_LEAD_URL || "http://127.0.0.1:5010";
24
+ const DASHBOARD = process.env.DASHBOARD_URL || "http://127.0.0.1:4319";
25
+ const MCP_URL = process.env.MCP_URL || "http://127.0.0.1:5020";
26
+ const CFG_PATH = path.join(os.homedir(), ".crewswarm", "crewswarm.json");
27
+ const SWARM_PATH = path.join(os.homedir(), ".crewswarm", "crewswarm.json");
28
+
29
+ // ── Output helpers ─────────────────────────────────────────────────────────────
30
+ const R="\x1b[0m", B="\x1b[1m", G="\x1b[32m", RE="\x1b[31m", Y="\x1b[33m", C="\x1b[36m", D="\x1b[2m";
31
+ const results = [];
32
+ let pass=0, fail=0, warn=0;
33
+
34
+ function check(name, status, detail="") {
35
+ results.push({ name, status, detail });
36
+ if (status === "pass") { pass++; if (!QUIET_MODE) console.log(` ${G}✓${R} ${name}${detail ? D+" "+detail+R : ""}`); }
37
+ else if (status === "warn") { warn++; console.log(` ${Y}⚠${R} ${name}${detail ? " "+detail : ""}`); }
38
+ else { fail++; console.log(` ${RE}✗${R} ${name}${detail ? " "+detail : ""}`); }
39
+ }
40
+
41
+ function section(title) {
42
+ if (!QUIET_MODE) console.log(`\n${B}${C}── ${title} ──${R}`);
43
+ }
44
+
45
+ function getToken() {
46
+ try { return JSON.parse(fs.readFileSync(CFG_PATH, "utf8"))?.rt?.authToken || ""; } catch { return ""; }
47
+ }
48
+
49
+ function authHeaders() {
50
+ const t = getToken();
51
+ return { "content-type": "application/json", ...(t ? { authorization: `Bearer ${t}` } : {}) };
52
+ }
53
+
54
+ async function ping(url, label, opts = {}) {
55
+ try {
56
+ const res = await fetch(url, { signal: AbortSignal.timeout(opts.timeout || 10000), headers: authHeaders() });
57
+ return { ok: res.ok || res.status < 500, status: res.status };
58
+ } catch (e) {
59
+ return { ok: false, error: e.message };
60
+ }
61
+ }
62
+
63
+ function cliCheck(cmd, label) {
64
+ try {
65
+ const out = execSync(cmd, { encoding: "utf8", timeout: 10000, stdio: ["pipe", "pipe", "pipe"] }).trim();
66
+ return { ok: true, version: out.split("\n")[0].trim().slice(0, 60) };
67
+ } catch (e) {
68
+ return { ok: false, error: e.message.slice(0, 80) };
69
+ }
70
+ }
71
+
72
+ // ── Run all checks in parallel ────────────────────────────────────────────────
73
+ async function run() {
74
+ if (!QUIET_MODE) {
75
+ console.log(`\n${B}${C}━━━ crewswarm Health Check ━━━${R}`);
76
+ console.log(`${D} ${new Date().toLocaleString()}${R}`);
77
+ }
78
+
79
+ // ── 1. Config files ──────────────────────────────────────────────────────────
80
+ section("Config");
81
+ const hasConfig = fs.existsSync(CFG_PATH);
82
+ const hasSwarm = fs.existsSync(SWARM_PATH);
83
+ check("~/.crewswarm/crewswarm.json", hasConfig ? "pass" : "fail", hasConfig ? "" : "run: bash install.sh");
84
+ check("~/.crewswarm/crewswarm.json", hasSwarm ? "pass" : "fail", hasSwarm ? "" : "run: bash install.sh");
85
+
86
+ const token = getToken();
87
+ check("Auth token", token ? "pass" : "fail", token ? `${token.slice(0,8)}…` : "missing rt.authToken");
88
+
89
+ // ── 2. API keys ──────────────────────────────────────────────────────────────
90
+ section("API Keys");
91
+ if (NO_SERVICES) {
92
+ check("API keys skipped", "pass", "--no-services mode");
93
+ } else {
94
+ let providers = {};
95
+ try { providers = JSON.parse(fs.readFileSync(SWARM_PATH, "utf8"))?.providers || {}; } catch {}
96
+ const configuredKeys = Object.entries(providers).filter(([,v]) => v?.apiKey?.length > 8);
97
+ if (configuredKeys.length === 0) {
98
+ check("API keys", "fail", "no provider keys found — open dashboard → Providers");
99
+ } else {
100
+ for (const [name, v] of configuredKeys) {
101
+ check(`${name} key`, "pass", `${v.apiKey.slice(0,8)}…`);
102
+ }
103
+ }
104
+ }
105
+
106
+ // ── 3. Services (parallel) ───────────────────────────────────────────────────
107
+ if (NO_SERVICES) {
108
+ section("Services");
109
+ check("services skipped", "pass", "--no-services mode");
110
+ } else {
111
+ section("Services");
112
+ const [crewLead, dashboard, mcpServer] = await Promise.all([
113
+ ping(`${CREW_LEAD}/health`, "crew-lead"),
114
+ ping(`${DASHBOARD}/`, "dashboard"), // dashboard serves HTML on /
115
+ ping(`${MCP_URL}/health`, "mcp-server"),
116
+ ]);
117
+
118
+ check("crew-lead :5010", crewLead.ok ? "pass" : "fail",
119
+ crewLead.ok ? `HTTP ${crewLead.status}` : crewLead.error || `HTTP ${crewLead.status}`);
120
+ check("dashboard :4319", dashboard.ok ? "pass" : "fail",
121
+ dashboard.ok ? `HTTP ${dashboard.status}` : (dashboard.error || `HTTP ${dashboard.status}`) + " — run: node scripts/dashboard.mjs");
122
+ check("mcp-server :5020", mcpServer.ok ? "pass" : "warn",
123
+ mcpServer.ok ? `HTTP ${mcpServer.status}` : "not running — start: npm run mcp");
124
+ }
125
+
126
+ // ── 4. Agents online ─────────────────────────────────────────────────────────
127
+ if (!NO_SERVICES) {
128
+ section("Agents");
129
+ try {
130
+ const res = await fetch(`${CREW_LEAD}/api/agents`, { headers: authHeaders(), signal: AbortSignal.timeout(5000) });
131
+ const d = await res.json();
132
+ const agents = d.agents || [];
133
+ // crew-lead /api/agents uses liveness field; dashboard /api/agents uses online/alive/liveness
134
+ const online = agents.filter(a => a.online || a.alive || a.liveness === "alive");
135
+ const coreAgents = ["crew-coder","crew-qa","crew-pm","crew-main","crew-fixer"];
136
+ check(`Agents online (${online.length}/${agents.length})`,
137
+ online.length > 0 ? "pass" : "warn",
138
+ online.length === 0 ? "bridges not started — run: npm run start-crew" : online.map(a => a.id?.replace("crew-","")).join(", ").slice(0,80));
139
+ for (const core of coreAgents) {
140
+ const a = agents.find(x => x.id === core);
141
+ const isOnline = a?.online || a?.alive || a?.liveness === "alive";
142
+ check(` ${core}`, isOnline ? "pass" : "warn", isOnline ? "" : "bridge not running");
143
+ }
144
+ } catch (e) {
145
+ check("Agents", "fail", `could not reach crew-lead: ${e.message}`);
146
+ }
147
+ }
148
+
149
+ // ── 5. CLI tools ─────────────────────────────────────────────────────────────
150
+ section("CLI Tools");
151
+ const [cursorCli, claudeCli, opencodeCli, nodeCli] = await Promise.all([
152
+ Promise.resolve(cliCheck("cursor --version 2>/dev/null || cursor-cli --version 2>/dev/null", "cursor")),
153
+ Promise.resolve(cliCheck("echo '' | timeout 3 claude --version 2>/dev/null || echo 'not found'", "claude")),
154
+ Promise.resolve(cliCheck("opencode --version 2>/dev/null || echo 'not found'", "opencode")),
155
+ Promise.resolve(cliCheck("node --version", "node")),
156
+ ]);
157
+
158
+ check("node", nodeCli.ok ? "pass" : "fail", nodeCli.version || nodeCli.error);
159
+ check("cursor cli", cursorCli.ok && !cursorCli.version?.includes("not found") ? "pass" : "warn",
160
+ cursorCli.version?.includes("not found") ? "install cursor CLI — Cursor → Settings → Install command" : (cursorCli.version || cursorCli.error));
161
+ check("claude code cli", claudeCli.ok && !claudeCli.version?.includes("not found") ? "pass" : "warn",
162
+ claudeCli.version?.includes("not found") ? "npm install -g @anthropic-ai/claude-code" : (claudeCli.version || claudeCli.error));
163
+ check("opencode cli", opencodeCli.ok && !opencodeCli.version?.includes("not found") ? "pass" : "warn",
164
+ opencodeCli.version?.includes("not found") ? "npm install -g opencode-ai" : (opencodeCli.version || opencodeCli.error));
165
+
166
+ // ── 6. MCP protocol (if server is up) ────────────────────────────────────────
167
+ const mcpServer = NO_SERVICES ? { ok: false } : (await ping(`${MCP_URL}/health`, "mcp-server"));
168
+ if (!NO_SERVICES && mcpServer.ok) {
169
+ section("MCP Protocol");
170
+ try {
171
+ const initRes = await fetch(`${MCP_URL}/mcp`, {
172
+ method: "POST",
173
+ headers: { "content-type": "application/json" },
174
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "initialize", params: { protocolVersion: "2024-11-05", clientInfo: { name: "health-check", version: "1.0" } } }),
175
+ signal: AbortSignal.timeout(4000),
176
+ });
177
+ const initData = await initRes.json();
178
+ check("MCP initialize", initData?.result?.serverInfo ? "pass" : "fail",
179
+ initData?.result?.serverInfo?.name || JSON.stringify(initData).slice(0,60));
180
+
181
+ const toolsRes = await fetch(`${MCP_URL}/mcp`, {
182
+ method: "POST",
183
+ headers: { "content-type": "application/json" },
184
+ body: JSON.stringify({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} }),
185
+ signal: AbortSignal.timeout(4000),
186
+ });
187
+ const toolsData = await toolsRes.json();
188
+ const toolCount = toolsData?.result?.tools?.length || 0;
189
+ check(`MCP tools/list (${toolCount} tools)`, toolCount >= 5 ? "pass" : "warn",
190
+ toolsData?.result?.tools?.map(t => t.name).join(", ").slice(0, 80));
191
+ } catch (e) {
192
+ check("MCP protocol", "fail", e.message);
193
+ }
194
+ }
195
+
196
+ // ── 7. Quick crew-lead chat ───────────────────────────────────────────────────
197
+ section("crew-lead Chat");
198
+ if (NO_SERVICES) {
199
+ check("chat skipped", "pass", "--no-services mode");
200
+ } else {
201
+ try {
202
+ const start = Date.now();
203
+ const res = await fetch(`${CREW_LEAD}/chat`, {
204
+ method: "POST",
205
+ headers: authHeaders(),
206
+ body: JSON.stringify({ message: "say: HEALTH_OK", sessionId: "health-check" }),
207
+ signal: AbortSignal.timeout(15000),
208
+ });
209
+ const d = await res.json();
210
+ const elapsed = Date.now() - start;
211
+ const reply = d.reply || d.message || "";
212
+ check("crew-lead responds", reply.length > 0 ? "pass" : "fail",
213
+ `${Math.round(elapsed/100)/10}s — "${reply.slice(0,60)}"`);
214
+ } catch (e) {
215
+ check("crew-lead chat", "fail", e.message);
216
+ }
217
+ }
218
+
219
+ // ── Summary ───────────────────────────────────────────────────────────────────
220
+ console.log(`\n${B}${pass + fail + warn} checks${R} ${G}${pass} pass${R} ${warn > 0 ? Y : ""}${warn} warn${R} ${fail > 0 ? RE : ""}${fail} fail${R}\n`);
221
+
222
+ if (JSON_MODE) {
223
+ console.log(JSON.stringify({ pass, fail, warn, results }, null, 2));
224
+ }
225
+
226
+ if (fail > 0) process.exit(1);
227
+ }
228
+
229
+ run().catch(e => { console.error(`[health-check] fatal: ${e.message}`); process.exit(1); });