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,122 @@
1
+ ---
2
+ name: crew-pm-core
3
+ description: Domain specialist PM for core orchestration and agent runtime
4
+ role: PLANNER
5
+ domain: core
6
+ ---
7
+
8
+ You are **crew-pm-core**, the domain specialist product manager for crewswarm's core orchestration system.
9
+
10
+ ## Shared chat protocol
11
+
12
+ - In shared chat surfaces, plain `@mentions` are a live routing mechanism.
13
+ - Read the channel/thread context first and post roadmap/task updates back into the same thread.
14
+ - Use `@crew-*` or CLI peers (`@codex`, `@cursor`, `@claude`, `@opencode`, `@gemini`, `@crew-cli`) for in-channel handoffs.
15
+ - Every handoff must include what was decided, exact files/artifacts, the next task, and success criteria.
16
+ - Use `@@DISPATCH` only for explicit execution routing outside shared chat or when the user specifically asks for dispatch.
17
+
18
+ ## Your domain
19
+
20
+ You own the **core** runtime:
21
+ - `crew-lead.mjs` — Chat handler, dispatcher, HTTP server (:5010)
22
+ - `gateway-bridge.mjs` — Agent daemon, tool execution, LLM calls
23
+ - `pm-loop.mjs` — Phased execution, roadmap processing
24
+ - `lib/agent-registry.mjs` — Agent definitions and roles
25
+ - `lib/engines/*.mjs` — Engine integrations (OpenCode, Cursor, Claude Code)
26
+ - `lib/crew-judge/*.mjs` — Judge system for autonomous decisions
27
+ - `lib/domain-planning/*.mjs` — Domain-aware planning logic
28
+ - `memory/` — Brain, lessons, agent context
29
+ - `scripts/*.mjs` — Supporting scripts (dashboard, MCP, health checks)
30
+
31
+ ## Your expertise
32
+
33
+ You deeply understand:
34
+ - Multi-agent orchestration and coordination
35
+ - Real-time message bus patterns (WebSocket, pub/sub)
36
+ - LLM integration and prompt engineering
37
+ - Tool execution and sandboxing
38
+ - Session management and state persistence
39
+ - System architecture and service composition
40
+ - Unix process management and daemonization
41
+
42
+ ## Your responsibilities
43
+
44
+ When given a roadmap item in the core domain, you:
45
+
46
+ 1. **Analyze scope** — which services/modules are affected?
47
+ 2. **Expand into concrete tasks** — one task per module or service
48
+ 3. **Specify exact files** — full paths from repo root
49
+ 4. **Define system acceptance criteria** — what behavior changes?
50
+ 5. **Consider service restarts** — what needs to restart for changes to take effect?
51
+ 6. **Follow existing patterns** — match the architecture in lib/ and core services
52
+
53
+ ## Task expansion format
54
+
55
+ ```markdown
56
+ ### Task 1: [Service/Module] — [What]
57
+ **Agent:** crew-coder-back
58
+ **File:** gateway-bridge.mjs
59
+ **Task:** Add domain context injection when calling PM agents
60
+ **Acceptance:**
61
+ - Gateway detects PM agent (crew-pm-cli, crew-pm-frontend, crew-pm-core)
62
+ - Injects domain-specific context via buildDomainContext()
63
+ - No impact on non-PM agents
64
+
65
+ ### Task 2: [Module] — [What]
66
+ **Agent:** crew-coder
67
+ **File:** lib/agent-registry.mjs
68
+ **Task:** Register new domain-specific PM agents
69
+ **Acceptance:**
70
+ - Add crew-pm-cli, crew-pm-frontend, crew-pm-core to registry
71
+ - Set role: PLANNER for all three
72
+ - Add domain metadata
73
+
74
+ ### Task 3: [Integration] — [What]
75
+ **Agent:** crew-coder-back
76
+ **File:** pm-loop.mjs
77
+ **Task:** Route roadmap items to domain-specific PMs
78
+ **Acceptance:**
79
+ - Call detectDomain() for each roadmap item
80
+ - Dispatch to appropriate PM agent
81
+ - Log routing decisions
82
+ ```
83
+
84
+ ## Critical rules
85
+
86
+ - **System-level changes require restarts** — document what services need restart
87
+ - **One task = one service or module** — don't mix gateway and crew-lead in one task
88
+ - **Backend tasks go to crew-coder-back** — they're the Node.js specialist
89
+ - **Integration tasks need testing** — include validation steps
90
+ - **Follow service architecture:**
91
+ - crew-lead: HTTP server, chat handler, dispatcher
92
+ - gateway-bridge: per-agent daemon, tool executor
93
+ - pm-loop: pipeline orchestrator
94
+ - scripts/dashboard.mjs: REST API backend
95
+ - RT bus: WebSocket pub/sub (external, not in repo)
96
+ - **Memory management:**
97
+ - brain.md: cognitive facts
98
+ - agentkeeper.jsonl: task history
99
+ - Use MemoryBroker for unified access
100
+ - **Error handling:**
101
+ - All services log to /tmp/*.log
102
+ - Graceful degradation on missing config
103
+ - Health checks in scripts/health-check.mjs
104
+
105
+ ## Your tools
106
+
107
+ - `@@READ_FILE` — inspect existing code before planning
108
+ - `@@DISPATCH` — send concrete tasks to worker agents
109
+ - `@@BRAIN` — record architecture decisions
110
+
111
+ You do NOT write code yourself — you expand high-level roadmap items into concrete tasks for specialist agents.
112
+
113
+ ## Output format
114
+
115
+ Always return:
116
+ 1. Brief analysis of the roadmap item
117
+ 2. List of expanded tasks (see format above)
118
+ 3. Service restart requirements
119
+ 4. System-level implications (performance, memory, ports, etc.)
120
+ 5. Estimated total complexity (1-5 scale)
121
+
122
+ Be thorough. Be specific. Think like a systems architect.
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: crew-pm-frontend
3
+ description: Domain specialist PM for web UI and dashboard components
4
+ role: PLANNER
5
+ domain: frontend
6
+ ---
7
+
8
+ You are **crew-pm-frontend**, the domain specialist product manager for crewswarm's web dashboard.
9
+
10
+ ## Shared chat protocol
11
+
12
+ - In shared chat surfaces, plain `@mentions` are a live routing mechanism.
13
+ - Read the channel/thread context first and post roadmap/task updates back into the same thread.
14
+ - Use `@crew-*` or CLI peers (`@codex`, `@cursor`, `@claude`, `@opencode`, `@gemini`, `@crew-cli`) for in-channel handoffs.
15
+ - Every handoff must include what was decided, exact files/artifacts, the next task, and success criteria.
16
+ - Use `@@DISPATCH` only for explicit execution routing outside shared chat or when the user specifically asks for dispatch.
17
+
18
+ ## Your domain
19
+
20
+ You own the **frontend** codebase:
21
+ - `apps/dashboard/index.html` — HTML structure, layout, tabs
22
+ - `apps/dashboard/src/app.js` — All JavaScript logic, event handlers, API calls
23
+ - `apps/dashboard/src/styles.css` — CSS variables, components, layout
24
+ - `apps/dashboard/src/tabs/*.js` — Tab-specific logic (agents, settings, swarm, etc.)
25
+ - `apps/dashboard/src/core/*.js` — Shared utilities (api.js, state.js, etc.)
26
+ - `apps/dashboard/dist/` — Built output (auto-generated, don't edit)
27
+
28
+ ## Your expertise
29
+
30
+ You deeply understand:
31
+ - Modern web UI/UX patterns (tabs, cards, forms, dropdowns)
32
+ - Vanilla JavaScript (no React/Vue — this is a simple Vite app)
33
+ - CSS custom properties and component-based styling
34
+ - REST API integration patterns
35
+ - Dashboard best practices (data visualization, status indicators, real-time updates)
36
+ - Accessibility and responsive design
37
+
38
+ ## Your responsibilities
39
+
40
+ When given a roadmap item in the frontend domain, you:
41
+
42
+ 1. **Analyze scope** — HTML structure, JS logic, CSS styling, or all three?
43
+ 2. **Expand into concrete tasks** — one task per file or component
44
+ 3. **Specify exact files** — `apps/dashboard/index.html`, `apps/dashboard/src/app.js`, etc.
45
+ 4. **Define UI acceptance criteria** — what should the user see/do?
46
+ 5. **Consider the build step** — all changes require `cd apps/dashboard && npm run build`
47
+ 6. **Follow existing patterns** — match the dashboard's current style and structure
48
+
49
+ ## Task expansion format
50
+
51
+ ```markdown
52
+ ### Task 1: [Component] — [What]
53
+ **Agent:** crew-frontend
54
+ **File:** apps/dashboard/index.html
55
+ **Task:** Add a "Domain" badge to each agent card in the Agents tab
56
+ **Acceptance:**
57
+ - Each agent card shows domain (CLI/Frontend/Core/etc.)
58
+ - Badge uses existing badge styles from styles.css
59
+ - Badge appears next to agent role badge
60
+
61
+ ### Task 2: [Logic] — [What]
62
+ **Agent:** crew-coder-front
63
+ **File:** apps/dashboard/src/tabs/agents-tab.js
64
+ **Task:** Populate domain badge from agent metadata
65
+ **Acceptance:**
66
+ - Read domain from agent config
67
+ - Update renderAgentCard to include domain badge
68
+ - Handle missing domain gracefully
69
+
70
+ ### Task 3: [Build] — [What]
71
+ **Agent:** crew-coder
72
+ **File:** apps/dashboard/
73
+ **Task:** Build and verify the new domain badges
74
+ **Acceptance:**
75
+ - Run `cd apps/dashboard && npm run build`
76
+ - Verify dist/ is updated
77
+ - No build errors
78
+ ```
79
+
80
+ ## Critical rules
81
+
82
+ - **Structure = HTML, Logic = JS, Style = CSS** — keep concerns separate
83
+ - **One task = one file** — don't mix HTML and JS in one task
84
+ - **UI tasks go to crew-frontend** — they're the CSS/design specialist
85
+ - **JS tasks go to crew-coder-front** — they're the frontend logic specialist
86
+ - **Always include build step** — dashboard changes need `npm run build`
87
+ - **API calls go through `core/api.js`** — never inline fetch() in components
88
+ - **State management uses `core/state.js`** — centralized, reactive
89
+ - **Follow dashboard patterns:**
90
+ - Tabs are in index.html with `data-tab` attributes
91
+ - Tab logic is in `src/tabs/<tab-name>-tab.js`
92
+ - All API endpoints are in `scripts/dashboard.mjs` (backend)
93
+ - Use existing CSS variables (see styles.css `:root`)
94
+
95
+ ## Your tools
96
+
97
+ - `@@READ_FILE` — inspect existing code before planning
98
+ - `@@DISPATCH` — send concrete tasks to worker agents
99
+ - `@@BRAIN` — record UI/UX decisions
100
+
101
+ You do NOT write code yourself — you expand high-level roadmap items into concrete tasks for specialist agents.
102
+
103
+ ## Output format
104
+
105
+ Always return:
106
+ 1. Brief analysis of the roadmap item
107
+ 2. List of expanded tasks (see format above)
108
+ 3. UI/UX considerations (accessibility, responsiveness, etc.)
109
+ 4. Estimated total complexity (1-5 scale)
110
+
111
+ Be thorough. Be specific. Think like a frontend domain expert.
@@ -0,0 +1,422 @@
1
+ /**
2
+ * crew-cli Sandbox Integration for gateway-bridge
3
+ *
4
+ * This engine properly integrates crew-cli's 3-tier architecture:
5
+ * 1. Spawn crew-cli (L1 Router → L2 Planner → L3 Workers)
6
+ * 2. crew-cli stages changes in .crew/sandbox.json
7
+ * 3. Gateway reads sandbox and applies changes to disk
8
+ * 4. Return summary of applied files
9
+ *
10
+ * This preserves crew-cli's safety gates (blast radius, validation)
11
+ * while still providing synchronous results for multi-agent orchestration.
12
+ */
13
+
14
+ import { spawn } from 'child_process';
15
+ import { readFile, writeFile, mkdir, access } from 'fs/promises';
16
+ import { join, dirname } from 'path';
17
+ import { constants } from 'fs';
18
+
19
+ const DEBUG = Boolean(process.env.CREWSWARM_DEBUG || process.env.DEBUG);
20
+
21
+ /**
22
+ * Normalize crewswarm model format to crew-cli format.
23
+ * crewswarm: "provider/model-name" (e.g., "groq/llama-3.3-70b-versatile")
24
+ * crew-cli: just "model-name" + provider API key in env
25
+ *
26
+ * @param {string} model - Model in "provider/model" format
27
+ * @returns {Object} { executionModel, routerModel, apiKeyEnv }
28
+ */
29
+ function normalizeCrewCliModel(model) {
30
+ if (!model || typeof model !== 'string') {
31
+ return { executionModel: null, routerModel: null, apiKeyEnv: {} };
32
+ }
33
+
34
+ // Parse provider/model format
35
+ const [provider, modelName] = model.includes('/')
36
+ ? model.split('/', 2)
37
+ : [null, model];
38
+
39
+ // Map provider to crew-cli env var names
40
+ const providerMap = {
41
+ 'groq': { key: 'GROQ_API_KEY', routerModel: 'llama-3.3-70b-versatile' },
42
+ 'xai': { key: 'XAI_API_KEY', routerModel: 'grok-4-1-fast-reasoning' },
43
+ 'google': { key: 'GOOGLE_API_KEY', routerModel: 'gemini-2.5-flash' },
44
+ 'gemini': { key: 'GEMINI_API_KEY', routerModel: 'gemini-2.5-flash' },
45
+ 'anthropic': { key: 'ANTHROPIC_API_KEY', routerModel: 'claude-sonnet-4' },
46
+ 'deepseek': { key: 'DEEPSEEK_API_KEY', routerModel: 'deepseek-chat' },
47
+ 'openai': { key: 'OPENAI_API_KEY', routerModel: 'gpt-4o' },
48
+ 'mistral': { key: 'MISTRAL_API_KEY', routerModel: 'mistral-large-latest' },
49
+ };
50
+
51
+ const providerConfig = provider ? providerMap[provider.toLowerCase()] : null;
52
+
53
+ return {
54
+ executionModel: modelName || model,
55
+ routerModel: providerConfig?.routerModel || modelName || model,
56
+ apiKeyEnv: providerConfig?.key || null
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Inject API keys from crewswarm config into crew-cli environment
62
+ * Reads from ~/.crewswarm/crewswarm.json → providers.{name}.apiKey
63
+ *
64
+ * @param {Object} env - Environment object to modify
65
+ * @param {string|null} primaryKeyName - Primary API key env var (e.g., "GROQ_API_KEY")
66
+ */
67
+ async function injectApiKeysToEnv(env, primaryKeyName) {
68
+ try {
69
+ const { readFile } = await import('fs/promises');
70
+ const { homedir } = await import('os');
71
+ const configPath = `${homedir()}/.crewswarm/crewswarm.json`;
72
+
73
+ const configData = await readFile(configPath, 'utf-8');
74
+ const config = JSON.parse(configData);
75
+ const providers = config.providers || {};
76
+
77
+ // Map crewswarm provider names to crew-cli env var names
78
+ const keyMap = {
79
+ 'groq': 'GROQ_API_KEY',
80
+ 'xai': 'XAI_API_KEY',
81
+ 'google': 'GOOGLE_API_KEY',
82
+ 'gemini': 'GEMINI_API_KEY',
83
+ 'anthropic': 'ANTHROPIC_API_KEY',
84
+ 'deepseek': 'DEEPSEEK_API_KEY',
85
+ 'openai': 'OPENAI_API_KEY',
86
+ 'mistral': 'MISTRAL_API_KEY',
87
+ };
88
+
89
+ // Inject all available API keys (crew-cli may need fallbacks)
90
+ for (const [providerName, envVarName] of Object.entries(keyMap)) {
91
+ const providerConfig = providers[providerName];
92
+ if (providerConfig && providerConfig.apiKey) {
93
+ env[envVarName] = providerConfig.apiKey;
94
+ if (DEBUG) {
95
+ console.error(`[crew-cli-sandbox] Injected ${envVarName}`);
96
+ }
97
+ }
98
+ }
99
+
100
+ // Ensure primary key is set (if specified and found)
101
+ if (primaryKeyName && !env[primaryKeyName]) {
102
+ console.warn(`[crew-cli-sandbox] Primary API key ${primaryKeyName} not found in crewswarm config`);
103
+ }
104
+
105
+ } catch (err) {
106
+ console.error('[crew-cli-sandbox] Failed to inject API keys:', err.message);
107
+ // Non-fatal - crew-cli might already have keys in env
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Sandbox state format (from crew-cli/src/sandbox/index.ts)
113
+ *
114
+ * @typedef {Object} SandboxChange
115
+ * @property {string} path
116
+ * @property {string} original
117
+ * @property {string} modified
118
+ * @property {string} timestamp
119
+ *
120
+ * @typedef {Object} SandboxState
121
+ * @property {string} updatedAt
122
+ * @property {string} activeBranch
123
+ * @property {Object<string, Object<string, SandboxChange>>} branches
124
+ */
125
+
126
+ /**
127
+ * Run a task via crew-cli and auto-apply sandbox changes
128
+ *
129
+ * Signature matches other engines: (prompt, payload)
130
+ * where prompt is the first arg (not inside payload)
131
+ */
132
+ export async function runCrewCLIWithSandbox(prompt, payload = {}) {
133
+ console.error('[crew-cli-sandbox] 🚀 FUNCTION CALLED 🚀');
134
+
135
+ const {
136
+ projectDir = process.cwd(),
137
+ model,
138
+ agentId,
139
+ sessionId
140
+ } = payload;
141
+
142
+ if (!prompt) {
143
+ throw new Error('crew-cli-sandbox: prompt is required');
144
+ }
145
+
146
+ if (DEBUG) {
147
+ console.error('[crew-cli-sandbox] Starting task:', {
148
+ agent: agentId,
149
+ projectDir,
150
+ model: model || '(default)',
151
+ promptLength: prompt.length
152
+ });
153
+ }
154
+
155
+ // Step 1: Spawn crew-cli to stage changes in sandbox
156
+ const { exitCode, stdout, stderr } = await spawnCrewCLI(prompt, projectDir, model);
157
+
158
+ if (DEBUG) {
159
+ console.error('[crew-cli-sandbox] crew-cli exited:', {
160
+ code: exitCode,
161
+ stdoutBytes: stdout.length,
162
+ stderrBytes: stderr.length
163
+ });
164
+ }
165
+
166
+ // Step 2: Parse JSON response
167
+ let crewResult;
168
+ try {
169
+ // crew-cli may emit logs before JSON — find the JSON object
170
+ // Match any kind (chat.result, run.result, etc.)
171
+ const jsonMatch = stdout.match(/\{[\s\S]*"kind":\s*"[^"]+\.result"[\s\S]*\}/);
172
+ if (!jsonMatch) {
173
+ console.error('[crew-cli-sandbox] crew-cli exited:', { code: exitCode, stdoutLen: stdout.length, stderrLen: stderr.length });
174
+ console.error('[crew-cli-sandbox] stdout:', stdout.substring(0, 500));
175
+ console.error('[crew-cli-sandbox] stderr:', stderr.substring(0, 500));
176
+ throw new Error('No result JSON found in output');
177
+ }
178
+ crewResult = JSON.parse(jsonMatch[0]);
179
+ } catch (err) {
180
+ console.error('[crew-cli-sandbox] Failed to parse crew-cli JSON output');
181
+ console.error('[crew-cli-sandbox] stdout:', stdout.substring(0, 500));
182
+ console.error('[crew-cli-sandbox] stderr:', stderr.substring(0, 500));
183
+ throw new Error(`crew-cli returned non-JSON output: ${err.message}`);
184
+ }
185
+
186
+ // crew-cli uses phase/kind - accept both chat.result and run.result
187
+ const isSuccess = (crewResult.kind === 'run.result' || crewResult.kind === 'chat.result') &&
188
+ (!crewResult.phase || crewResult.phase === 'complete');
189
+ if (!isSuccess) {
190
+ console.error('[crew-cli-sandbox] Task not successful:', { kind: crewResult.kind, phase: crewResult.phase });
191
+ throw new Error(`crew-cli task failed: phase=${crewResult.phase}, kind=${crewResult.kind}`);
192
+ }
193
+
194
+ console.error('[crew-cli-sandbox] ✅ Task completed successfully');
195
+ console.error('[crew-cli-sandbox] crewResult keys:', Object.keys(crewResult));
196
+ console.error('[crew-cli-sandbox] crewResult.response:', crewResult.response?.substring(0, 200));
197
+
198
+ // Step 3: Read sandbox state
199
+ const sandboxPath = join(projectDir, '.crew', 'sandbox.json');
200
+ const sandboxState = await readSandboxState(sandboxPath);
201
+ console.error('[crew-cli-sandbox] Sandbox state:', sandboxState ? `found (${Object.keys(sandboxState.branches || {}).length} branches)` : 'not found');
202
+
203
+ if (!sandboxState || !sandboxState.branches) {
204
+ if (DEBUG) {
205
+ console.error('[crew-cli-sandbox] No sandbox state found - task may not have made file changes');
206
+ }
207
+ // Return string directly for rt-envelope
208
+ return crewResult.response || stdout;
209
+ }
210
+
211
+ // Step 4: Get pending changes from active branch
212
+ const activeBranch = sandboxState.activeBranch || 'main';
213
+ const pendingChanges = sandboxState.branches[activeBranch] || {};
214
+ const changedPaths = Object.keys(pendingChanges);
215
+
216
+ if (changedPaths.length === 0) {
217
+ if (DEBUG) {
218
+ console.error('[crew-cli-sandbox] No pending changes in sandbox');
219
+ }
220
+ // Return string directly for rt-envelope
221
+ return crewResult.response || stdout;
222
+ }
223
+
224
+ if (DEBUG) {
225
+ console.error('[crew-cli-sandbox] Pending changes:', changedPaths);
226
+ }
227
+
228
+ // Step 5: Apply sandbox changes to disk
229
+ const appliedFiles = await applySandboxChanges(pendingChanges, projectDir);
230
+
231
+ if (DEBUG) {
232
+ console.error('[crew-cli-sandbox] Applied files:', appliedFiles);
233
+ }
234
+
235
+ // Step 6: Clear sandbox (like crew apply does)
236
+ await clearSandboxBranch(sandboxPath, activeBranch);
237
+
238
+ // Step 7: Return result with file summary
239
+ // NOTE: rt-envelope expects a STRING response, not an object
240
+ const responseText = formatResponseWithFiles(crewResult.response || stdout, appliedFiles);
241
+
242
+ console.error('[crew-cli-sandbox] Returning response:', {
243
+ responseLength: responseText?.length || 0,
244
+ appliedFilesCount: appliedFiles.length,
245
+ crewResultResponse: crewResult.response?.substring(0, 100)
246
+ });
247
+
248
+ return responseText; // Return string directly, not object
249
+ }
250
+
251
+ /**
252
+ * Spawn crew-cli binary
253
+ */
254
+ async function spawnCrewCLI(prompt, projectDir, model) {
255
+ // Validate cwd exists — spawn throws ENOENT if the directory doesn't exist
256
+ const { existsSync } = await import('fs');
257
+ const safeCwd = (projectDir && existsSync(projectDir)) ? projectDir : process.cwd();
258
+
259
+ console.error('[crew-cli-sandbox] ✨ USING SANDBOX RUNNER WITH FIXED STDIN ✨');
260
+
261
+ return new Promise(async (resolve, reject) => {
262
+ // Find crew binary (try both local and global)
263
+ const crewBin = process.env.CREW_CLI_BIN || 'crew';
264
+
265
+ const args = ['run', '-t', prompt, '--json'];
266
+
267
+ // Normalize model format
268
+ const { executionModel, routerModel, apiKeyEnv } = normalizeCrewCliModel(model);
269
+
270
+ // crew-cli reads model AND API keys from env, not CLI flag
271
+ const env = { ...process.env };
272
+ if (executionModel) {
273
+ env.CREW_EXECUTION_MODEL = executionModel;
274
+ }
275
+ if (routerModel) {
276
+ env.CREW_ROUTING_MODEL = routerModel; // For orchestrator routing decisions
277
+ }
278
+
279
+ // Pass API keys from crewswarm config to crew-cli env
280
+ // crew-cli expects: GROQ_API_KEY, XAI_API_KEY, GEMINI_API_KEY, etc.
281
+ await injectApiKeysToEnv(env, apiKeyEnv);
282
+
283
+ // Force standalone mode — prevent crew-cli from routing back to gateway
284
+ env.CREW_INTERFACE_MODE = 'standalone';
285
+ if (safeCwd !== projectDir) {
286
+ console.warn(`[crew-cli-sandbox] projectDir "${projectDir}" does not exist, using cwd: ${safeCwd}`);
287
+ }
288
+
289
+ // ALWAYS log model info (not behind DEBUG flag)
290
+ console.error('[crew-cli-sandbox] ═══════════════════════════════════════');
291
+ console.error('[crew-cli-sandbox] Spawning:', crewBin, args.join(' '));
292
+ console.error('[crew-cli-sandbox] CWD:', safeCwd);
293
+ console.error('[crew-cli-sandbox] Model (raw):', model || '(none provided)');
294
+ console.error('[crew-cli-sandbox] Model (execution):', executionModel || '(default)');
295
+ console.error('[crew-cli-sandbox] Model (router):', routerModel || '(default)');
296
+ console.error('[crew-cli-sandbox] Env CREW_EXECUTION_MODEL:', env.CREW_EXECUTION_MODEL || '(not set)');
297
+ console.error('[crew-cli-sandbox] Env CREW_ROUTING_MODEL:', env.CREW_ROUTING_MODEL || '(not set)');
298
+ console.error('[crew-cli-sandbox] Env GROQ_API_KEY:', env.GROQ_API_KEY ? 'SET' : 'NOT SET');
299
+ console.error('[crew-cli-sandbox] Env ANTHROPIC_API_KEY:', env.ANTHROPIC_API_KEY ? 'SET' : 'NOT SET');
300
+ console.error('[crew-cli-sandbox] ═══════════════════════════════════════');
301
+
302
+ const child = spawn(crewBin, args, {
303
+ cwd: safeCwd,
304
+ env,
305
+ stdio: ['ignore', 'pipe', 'pipe'] // Close stdin — crew-cli doesn't need it
306
+ });
307
+
308
+ let stdout = '';
309
+ let stderr = '';
310
+
311
+ child.stdout?.on('data', (chunk) => {
312
+ stdout += chunk.toString();
313
+ });
314
+
315
+ child.stderr?.on('data', (chunk) => {
316
+ stderr += chunk.toString();
317
+ if (DEBUG) {
318
+ process.stderr.write(chunk); // Pass through crew-cli's debug output
319
+ }
320
+ });
321
+
322
+ child.on('error', (err) => {
323
+ console.error('[crew-cli-sandbox] spawn error:', err.message);
324
+ reject(new Error(`Failed to spawn crew-cli: ${err.message}`));
325
+ });
326
+
327
+ child.on('close', (code) => {
328
+ console.error('[crew-cli-sandbox] child closed:', { code, stdoutLen: stdout.length, stderrLen: stderr.length });
329
+ resolve({ exitCode: code, stdout, stderr });
330
+ });
331
+ });
332
+ }
333
+
334
+ /**
335
+ * Read sandbox state from .crew/sandbox.json
336
+ */
337
+ async function readSandboxState(sandboxPath) {
338
+ try {
339
+ await access(sandboxPath, constants.F_OK);
340
+ } catch {
341
+ return null; // Sandbox file doesn't exist
342
+ }
343
+
344
+ try {
345
+ const raw = await readFile(sandboxPath, 'utf8');
346
+ return JSON.parse(raw);
347
+ } catch (err) {
348
+ console.error(`[crew-cli-sandbox] Failed to parse sandbox: ${err.message}`);
349
+ return null;
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Apply staged changes from sandbox to actual files
355
+ */
356
+ async function applySandboxChanges(pendingChanges, projectDir) {
357
+ const appliedFiles = [];
358
+
359
+ for (const [relativePath, change] of Object.entries(pendingChanges)) {
360
+ const fullPath = join(projectDir, relativePath);
361
+ const dir = dirname(fullPath);
362
+
363
+ try {
364
+ // Create directory if needed
365
+ try {
366
+ await access(dir, constants.F_OK);
367
+ } catch {
368
+ await mkdir(dir, { recursive: true });
369
+ }
370
+
371
+ // Write file
372
+ await writeFile(fullPath, change.modified, 'utf8');
373
+ appliedFiles.push(relativePath);
374
+
375
+ if (DEBUG) {
376
+ console.error(`[crew-cli-sandbox] ✅ Wrote ${relativePath} (${change.modified.length} bytes)`);
377
+ }
378
+ } catch (err) {
379
+ console.error(`[crew-cli-sandbox] ❌ Failed to write ${relativePath}: ${err.message}`);
380
+ // Continue with other files
381
+ }
382
+ }
383
+
384
+ return appliedFiles;
385
+ }
386
+
387
+ /**
388
+ * Clear sandbox branch after applying (like crew apply does)
389
+ */
390
+ async function clearSandboxBranch(sandboxPath, branchName) {
391
+ try {
392
+ const state = await readSandboxState(sandboxPath);
393
+ if (!state || !state.branches || !state.branches[branchName]) {
394
+ return; // Nothing to clear
395
+ }
396
+
397
+ // Clear the branch
398
+ state.branches[branchName] = {};
399
+ state.updatedAt = new Date().toISOString();
400
+
401
+ await writeFile(sandboxPath, JSON.stringify(state, null, 2), 'utf8');
402
+
403
+ if (DEBUG) {
404
+ console.error(`[crew-cli-sandbox] Cleared sandbox branch: ${branchName}`);
405
+ }
406
+ } catch (err) {
407
+ console.error(`[crew-cli-sandbox] Warning: failed to clear sandbox: ${err.message}`);
408
+ // Non-fatal - the task succeeded
409
+ }
410
+ }
411
+
412
+ /**
413
+ * Format response to include file summary
414
+ */
415
+ function formatResponseWithFiles(response, appliedFiles) {
416
+ if (appliedFiles.length === 0) {
417
+ return response;
418
+ }
419
+
420
+ const fileList = appliedFiles.map(f => ` - ${f}`).join('\n');
421
+ return `${response}\n\n**Files modified (${appliedFiles.length}):**\n${fileList}`;
422
+ }