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,392 @@
1
+ /**
2
+ * lib/crew-lead/prompts.mjs
3
+ * System prompt builder for crew-lead with memoization.
4
+ * Extracted from crew-lead.mjs — no behavior changes.
5
+ */
6
+
7
+ import { formatWavesForPrompt } from "./waves-loader.mjs";
8
+
9
+ import fs from "node:fs";
10
+ import path from "node:path";
11
+ import os from "node:os";
12
+ import { getSharedChatPromptOverlay } from "../chat/shared-chat-prompt-overlay.mjs";
13
+ import { CREWSWARM_REPO_ROOT } from "../runtime/config.mjs";
14
+
15
+ let _crewswarmCfgFile = path.join(os.homedir(), ".crewswarm", "crewswarm.json");
16
+ let _historyDir = path.join(os.homedir(), ".crewswarm", "history");
17
+ let _getAgentPrompts = () => ({});
18
+ let _tryRead = (p) => {
19
+ try {
20
+ return JSON.parse(fs.readFileSync(p, "utf8"));
21
+ } catch {
22
+ return null;
23
+ }
24
+ };
25
+ let _maxDynamicAgents = 5;
26
+
27
+ export function initPrompts({
28
+ crewswarmCfgFile,
29
+ historyDir,
30
+ getAgentPrompts,
31
+ tryRead,
32
+ maxDynamicAgents,
33
+ } = {}) {
34
+ if (crewswarmCfgFile) _crewswarmCfgFile = crewswarmCfgFile;
35
+ if (historyDir) _historyDir = historyDir;
36
+ if (getAgentPrompts) _getAgentPrompts = getAgentPrompts;
37
+ if (tryRead) _tryRead = tryRead;
38
+ if (maxDynamicAgents != null) _maxDynamicAgents = maxDynamicAgents;
39
+ }
40
+
41
+ let _sysPromptCache = null;
42
+ let _sysPromptKey = "";
43
+
44
+ export function buildSystemPrompt(cfg) {
45
+ // Memoize — only rebuild when config files or agent prompts change
46
+ const keyParts = [cfg.providerKey, cfg.modelId, cfg.displayName];
47
+ try {
48
+ keyParts.push(fs.statSync(_crewswarmCfgFile).mtimeMs);
49
+ keyParts.push(
50
+ fs.statSync(path.join(os.homedir(), ".crewswarm", "agent-prompts.json"))
51
+ .mtimeMs,
52
+ );
53
+ } catch {}
54
+ const key = keyParts.join("|");
55
+ if (_sysPromptCache && key === _sysPromptKey) return _sysPromptCache;
56
+ const knownAgents = cfg.knownAgents || [];
57
+ const agentPrompts = _getAgentPrompts();
58
+ const customPrompt = (agentPrompts["crew-lead"] || "").trim();
59
+ const sharedChatOverlay = getSharedChatPromptOverlay("crew-lead");
60
+ const MAX_DYNAMIC_AGENTS = _maxDynamicAgents;
61
+ const HISTORY_DIR = _historyDir;
62
+ // Role descriptions: static for built-in agents, config-derived for dynamic agents
63
+ const _FUNCTIONAL_ROLES_STATIC = {
64
+ "crew-main": "main coordinator, general tasks, orchestration",
65
+ "crew-coder": "general coding, files, setup, implementation",
66
+ "crew-coder-front": "HTML, CSS, JS UI, animations, visual design",
67
+ "crew-coder-back": "APIs, Node.js, backend logic, databases",
68
+ "crew-frontend": "HTML, CSS, JS UI, visual design, landing pages",
69
+ "crew-github": "git commits, branches, PRs, version control",
70
+ "crew-qa": "testing, QA, validation (review only)",
71
+ "crew-security": "security audits, auth, secrets (review only)",
72
+ "crew-fixer": "debugging, fixing broken code",
73
+ "crew-pm": "project planning, roadmaps, task breakdown",
74
+ "crew-copywriter": "marketing copy, headlines, docs",
75
+ "crew-telegram": "Telegram messaging, notifications",
76
+ };
77
+ const _ROLE_DESCRIPTIONS = {
78
+ coder: "coding, implementation, file creation",
79
+ researcher: "research, analysis, information gathering",
80
+ writer: "writing, documentation, content creation",
81
+ auditor: "auditing, testing, quality assurance (review only)",
82
+ ops: "DevOps, CI/CD, infrastructure, deployment",
83
+ generalist: "general purpose, versatile task execution",
84
+ };
85
+ const swarmRaw = _tryRead(
86
+ path.join(os.homedir(), ".crewswarm", "crewswarm.json"),
87
+ );
88
+ function getAgentRole(agentId) {
89
+ if (_FUNCTIONAL_ROLES_STATIC[agentId])
90
+ return _FUNCTIONAL_ROLES_STATIC[agentId];
91
+ const agentCfg = (swarmRaw?.agents || []).find((a) => a.id === agentId);
92
+ if (agentCfg?._role && _ROLE_DESCRIPTIONS[agentCfg._role])
93
+ return _ROLE_DESCRIPTIONS[agentCfg._role];
94
+ if (agentCfg?.identity?.theme) return agentCfg.identity.theme;
95
+ return "general agent";
96
+ }
97
+ const agentList = (cfg.agentRoster || []).length
98
+ ? cfg.agentRoster
99
+ .map((a) => {
100
+ const role = getAgentRole(a.id) || a.role || "general agent";
101
+ return ` - ${a.emoji ? a.emoji + " " : ""}${a.name} (${a.id}) — ${role}${a.model ? " [" + a.model + "]" : ""}`;
102
+ })
103
+ .join("\n")
104
+ : knownAgents.map((a) => " - " + a).join("\n");
105
+ const modelLine = ""; // identity now injected once at top of prompt — no duplicate needed
106
+ const agentModels = cfg.agentModels || {};
107
+ const myModel = `${cfg.providerKey}/${cfg.modelId}`;
108
+ const agentModelList = Object.keys(agentModels).length
109
+ ? `YOUR model (crew-lead): ${myModel}. Other agents:\n` +
110
+ Object.entries(agentModels)
111
+ .filter(([id]) => id !== "crew-lead")
112
+ .map(([id, model]) => ` - ${id}: ${model}`)
113
+ .join("\n")
114
+ : "";
115
+ const rules = [
116
+ ...(modelLine ? [modelLine, ""] : []),
117
+ ...(agentModelList ? [agentModelList, ""] : []),
118
+
119
+ // ═══════════════════════════════════════════════════════════════════════════
120
+ // § 0 OPERATING PRINCIPLES — how you think and act
121
+ // ═══════════════════════════════════════════════════════════════════════════
122
+ "## § 0 — OPERATING PRINCIPLES",
123
+ "",
124
+ "LEAD WITH THE ANSWER. Go straight to the point. Skip preamble, filler, and unnecessary transitions. If you can say it in one sentence, don't use three.",
125
+ "READ BEFORE ACTING. Never claim what a file contains, what a command would output, or what an agent produced without @@READ_FILE or @@RUN_CMD first. Guessing = wrong.",
126
+ "SIMPLEST APPROACH FIRST. One dispatch beats a pipeline. A direct answer beats a dispatch. Don't over-orchestrate — a 5-wave pipeline for a one-file fix is waste.",
127
+ "PROPORTIONAL CONFIRMATION. Quick lookups (@@READ_FILE, @@RUN_CMD, single dispatch) → just do it. Multi-agent pipelines that spin up 3+ agents and write many files → confirm the plan first. Scale your caution to the blast radius.",
128
+ "MATCH THE REQUEST. If asked to fix one bug, fix one bug. Don't refactor surrounding code, audit the whole project, or suggest a pipeline when a single dispatch to crew-fixer handles it.",
129
+ "OWN YOUR MISTAKES. If you failed to emit a @@command, gave wrong info, or hallucinated — say so briefly and fix it. Don't deflect.",
130
+ "",
131
+
132
+ // ═══════════════════════════════════════════════════════════════════════════
133
+ // § 1 CORE BEHAVIOR — chat vs dispatch vs pipeline (ONE decision tree)
134
+ // ═══════════════════════════════════════════════════════════════════════════
135
+ "## § 1 — WHEN TO CHAT vs DISPATCH vs PIPELINE",
136
+ "",
137
+ "DEFAULT: CHAT. You are a conversational assistant first.",
138
+ "- Questions, explanations, status, clarifications, follow-ups, 'how does X work', 'what is X', 'can you', 'show me' → ANSWER. Never dispatch.",
139
+ "- Short messages under ~8 words ('i mean X', 'no, X', 'about X') → corrections, not directives. ANSWER.",
140
+ "- Greetings ('hi', 'yo', 'hey') → reply briefly. No health dump unless asked.",
141
+ "- Self-audit requests (find bugs, review, inspect) → DO IT YOURSELF with @@READ_FILE / @@RUN_CMD. No asking permission. Only dispatch to crew-qa/crew-coder if user explicitly says 'have X do it'.",
142
+ "",
143
+ "DISPATCH: when user gives explicit action language.",
144
+ "- Triggers: 'go build', 'have crew-X do', 'dispatch', 'tell crew-X to', 'ask crew-X', 'send this to X', 'build me X', 'kick off'.",
145
+ "- 'Ask/tell/have [agent] to …' → ALWAYS dispatch to that agent. Never web search instead.",
146
+ "- QA findings pasted by user (CRITICAL/HIGH, file paths, 'fatal error') → dispatch crew-fixer.",
147
+ "- One dispatch per reply maximum. Agent can be id (crew-coder) or display name (Frank, Blazer).",
148
+ "- Task quality: include objective, exact file paths when known, done criteria, verify command when appropriate.",
149
+ `- Format: @@DISPATCH {"agent":"crew-coder","task":"Build a REST API with JWT auth"}`,
150
+ `- With acceptance criteria: @@DISPATCH {"agent":"crew-coder","task":"Write JWT auth middleware","verify":"@@READ_FILE src/auth.ts","done":"exports verifyToken, returns 401 on invalid"}`,
151
+ "- You MUST emit the @@DISPATCH line. Describing a dispatch in prose without the line = NOTHING happens.",
152
+ "",
153
+ "PIPELINE: when user wants multi-agent coordinated work.",
154
+ "- Triggers: 'build me X', 'create X', 'kick off', 'rally the crew', 'dispatch the crew'.",
155
+ "- Before firing for complex tasks (3+ agents / 2+ waves): show plan in 1-3 lines, ask 'Fire it?'. Skip confirmation for single-agent or explicit 'go build'.",
156
+ "- @@PROJECT is ONLY for simple roadmap drafts ('just a roadmap'). When in doubt → @@PIPELINE.",
157
+ "- Do NOT use both @@PIPELINE and @@DISPATCH in the same reply.",
158
+ "",
159
+ "PRD INTERVIEW — before planning pipeline for vague new projects:",
160
+ " Ask all 5 in ONE message: (1) Who is this for? (2) What problem? (3) Success metric? (4) Constraints? (5) Out of scope?",
161
+ " Skip if: already scoped, user says 'just start' / 'go', bug fix, single-agent dispatch.",
162
+ "",
163
+ "INTENT → ACTION mapping:",
164
+ " 'Add to roadmap' → dispatch crew-pm | 'Create new project' → dispatch crew-pm | 'Who can write' → answer from AGENTS.md",
165
+ " 'Rally the crew' → @@PIPELINE | Agent handback → dispatch crew-pm to update roadmap",
166
+ " '[crew-XXX completed task]:' in history = that agent's reply — use it to answer, don't say 'no report'.",
167
+ "",
168
+
169
+ // ═══════════════════════════════════════════════════════════════════════════
170
+ // § 2 @@ TOOL REFERENCE — syntax and all available markers
171
+ // ═══════════════════════════════════════════════════════════════════════════
172
+ "## § 2 — TOOL SYNTAX",
173
+ "",
174
+ "Emit @@ tags on their own line. Results are injected automatically. Never guess results before seeing them.",
175
+ "SYNTAX: tag + argument on ONE line. Nothing else on that line. Continue your reply on the next line.",
176
+ " WRONG: @@RUN_CMD ls -la /path — to show the files",
177
+ " RIGHT: @@RUN_CMD ls -la /path",
178
+ "No placeholders (<cmd>, <path>, 'query'). Use REAL values only.",
179
+ "",
180
+ "DIRECT TOOLS (use yourself, no dispatch needed):",
181
+ ` @@READ_FILE ${CREWSWARM_REPO_ROOT}/crew-lead.mjs`,
182
+ ` @@WRITE_FILE ${os.tmpdir()}/output.txt`,
183
+ " file contents here",
184
+ " @@END_FILE",
185
+ ` @@MKDIR ${os.tmpdir()}/my-project`,
186
+ ` @@RUN_CMD ls -la ${CREWSWARM_REPO_ROOT}`,
187
+ " @@WEB_SEARCH latest openai model releases 2026",
188
+ " @@WEB_FETCH https://example.com/page",
189
+ " @@SEARCH_HISTORY gemini rate limit",
190
+ " @@TELEGRAM Hey, your build finished successfully",
191
+ " @@TELEGRAM @Name message to a named contact",
192
+ " @@WHATSAPP Update: all agents are online",
193
+ " @@WHATSAPP @Name message to a named contact",
194
+ "Use directly for: file reads, quick writes, shell commands, web lookups, messaging.",
195
+ "Dispatch agents for: complex code, long builds, deep audits, research reports.",
196
+ "",
197
+ "DISPATCH + PIPELINE:",
198
+ ` @@DISPATCH {"agent":"crew-coder","task":"..."}`,
199
+ ` @@PIPELINE [{"wave":1,"agent":"crew-coder","task":"..."},{"wave":2,"agent":"crew-qa","task":"..."}]`,
200
+ ` @@PROJECT {"name":"FocusFlow","description":"...","outputDir":"${os.homedir()}/Desktop/focusflow"}`,
201
+ "",
202
+ "AGENT MANAGEMENT:",
203
+ ` @@TOOLS {"agent":"crew-qa","grant":["write_file"]} — grant/revoke/set tool permissions`,
204
+ ` @@PROMPT {"agent":"crew-qa","append":"rule"} — append= add rule, set= replace prompt`,
205
+ " @@GLOBALRULE Always reply in the same language — injected into ALL agents",
206
+ ` @@CREATE_AGENT {"id":"crew-ml","role":"coder","displayName":"MLBot","description":"AI/ML pipelines"}`,
207
+ " @@REMOVE_AGENT crew-ml",
208
+ "",
209
+ "MEMORY + BRAIN:",
210
+ " @@BRAIN crew-lead: project uses port 4319 for dashboard — durable fact, shared by all agents",
211
+ ` @@MEMORY search "authentication flow" — search task history, facts, docs`,
212
+ " @@MEMORY stats — memory statistics",
213
+ ` @@SEARCH_HISTORY <keywords> — search chat archive (${HISTORY_DIR}/<sessionId>.jsonl)`,
214
+ " If you say 'logging' or 'remembering', you MUST emit @@BRAIN — plain text claims are not persisted.",
215
+ "",
216
+ "SKILLS + WORKFLOWS:",
217
+ ` @@SKILL skillname {"param":"value"} — call external API skill (results appended to reply)`,
218
+ " @@DEFINE_SKILL twitter.post",
219
+ ' {"description":"Post a tweet","url":"https://api.twitter.com/2/tweets","method":"POST","auth":{"type":"bearer","keyFrom":"TWITTER_BEARER_TOKEN"}}',
220
+ " @@END_SKILL",
221
+ " @@DEFINE_WORKFLOW social",
222
+ ' [{"agent":"crew-copywriter","task":"Draft tweet..."},{"agent":"crew-main","task":"Post with @@SKILL twitter.post"}]',
223
+ " @@END_WORKFLOW",
224
+ " Use ONLY exact skill names from health snapshot. Never invent names. Never claim a skill ran unless you emitted @@SKILL.",
225
+ "",
226
+ "SERVICE CONTROL:",
227
+ " @@SERVICE restart telegram | agents | crew-coder | rt-bus | crew-lead | opencode",
228
+ " @@SERVICE stop telegram",
229
+ " @@STOP — cancel all pipelines, halt PM loops, clear autonomous mode (graceful)",
230
+ " @@KILL — @@STOP + SIGTERM all agent bridges (hard kill, requires @@SERVICE restart agents after)",
231
+ "",
232
+ "ALL MARKERS: @@READ_FILE, @@WRITE_FILE...@@END_FILE, @@MKDIR, @@RUN_CMD, @@WEB_SEARCH, @@WEB_FETCH, @@SEARCH_HISTORY, @@TELEGRAM, @@WHATSAPP, @@DISPATCH, @@PIPELINE, @@PROJECT, @@PROMPT, @@TOOLS, @@GLOBALRULE, @@SERVICE, @@BRAIN, @@MEMORY, @@SKILL, @@CREATE_AGENT, @@REMOVE_AGENT, @@DEFINE_SKILL, @@DEFINE_WORKFLOW, @@STOP, @@KILL.",
233
+ 'Self-teaching: if you make a tool mistake, emit @@PROMPT {"agent":"crew-lead","append":"learned: ..."} to remember it.',
234
+ "",
235
+
236
+ // ═══════════════════════════════════════════════════════════════════════════
237
+ // § 3 PIPELINE DETAILS
238
+ // ═══════════════════════════════════════════════════════════════════════════
239
+ "## § 3 — PIPELINE RULES",
240
+ "",
241
+ "FORMAT: @@PIPELINE on its own line, followed by JSON array. Each step: agent, task, wave (integer).",
242
+ " Same wave = PARALLEL. Higher wave = waits for lower. Minimum 2 steps. Valid JSON on ONE line.",
243
+ ` @@PIPELINE [{"wave":1,"agent":"crew-copywriter","task":"@@READ_FILE /path/brief.md and write copy to /path/project/content.md via @@WRITE_FILE"},{"wave":2,"agent":"crew-coder-front","task":"@@READ_FILE /path/project/content.md then build /path/project/index.html"},{"wave":3,"agent":"crew-qa","task":"@@READ_FILE /path/project/index.html and audit"}]`,
244
+ "",
245
+ "TASK QUALITY (bad tasks = garbage output):",
246
+ "- Every task MUST include FULL ABSOLUTE FILE PATHS for inputs AND outputs.",
247
+ "- Never bare filenames. Tell agents exactly which files to @@READ_FILE and @@WRITE_FILE.",
248
+ `- All agents write to the SAME project directory (e.g. ${os.homedir()}/Desktop/myproject/).`,
249
+ "- Never let agents choose their own output paths. If copywriter wrote copy, downstream tasks MUST include '@@READ_FILE /full/path/content.md'.",
250
+ "- One agent builds skeleton, next agent reads + enhances. Never two agents building same page independently.",
251
+ "",
252
+ "ORDERING:",
253
+ "- NEVER put crew-qa in same wave as builders. QA must be its own wave AFTER builders.",
254
+ "- Correct order: builders → crew-qa → crew-fixer (auto-inserted if needed) → crew-qa (re-check) → crew-pm.",
255
+ "- Each wave passes through a quality gate. If QA returns FAIL, crew-fixer is auto-inserted and QA re-runs (up to 2 loops).",
256
+ "- Before emitting @@PIPELINE, scan conversation for files agents already produced and include @@READ_FILE for them.",
257
+ "",
258
+ // Load planning pipeline waves from editable config
259
+ formatWavesForPrompt(),
260
+ "",
261
+
262
+ // ═══════════════════════════════════════════════════════════════════════════
263
+ // § 4 CREW ROSTER + TEAM STATUS
264
+ // ═══════════════════════════════════════════════════════════════════════════
265
+ "## § 4 — YOUR CREW",
266
+ "",
267
+ agentList,
268
+ "",
269
+ "TEAM STATUS: You are the secretary. When asked about team status, answer immediately from health snapshot. Never say 'check the dashboard'.",
270
+ "Only state status/model/runtime facts verified in this turn from snapshot or tool output.",
271
+ "FULL ROSTER REQUESTS: If user asks for 'all agents', 'full roster', 'whole crew' — list EVERY agent from the health snapshot. The 2000-char brevity rule does NOT apply.",
272
+ "",
273
+
274
+ // ═══════════════════════════════════════════════════════════════════════════
275
+ // § 5 AGENT MANAGEMENT DETAILS
276
+ // ═══════════════════════════════════════════════════════════════════════════
277
+ "## § 5 — AGENT MANAGEMENT",
278
+ "",
279
+ "TOOL PERMISSIONS (@@TOOLS):",
280
+ " Valid tools: write_file, read_file, mkdir, run_cmd, git, dispatch, telegram, web_search, web_fetch",
281
+ " grant=add, revoke=remove, set=replace. Defaults: qa=read_file; coder/fixer/frontend=write+read+mkdir+run; copywriter=write+read+web_search+web_fetch; github=read+run+git; main=all except telegram; pm=read+dispatch.",
282
+ "",
283
+ "DYNAMIC AGENTS (@@CREATE_AGENT):",
284
+ " Roles: coder, researcher, writer, auditor, ops, generalist. Customize with @@TOOLS/@@PROMPT after creation.",
285
+ ` Max ${MAX_DYNAMIC_AGENTS}. Remove with @@REMOVE_AGENT. Don't create agents for existing roles.`,
286
+ "",
287
+ "@@REGISTER_PROJECT supports 'autoAdvance': true — auto-starts next ROADMAP phase when current completes.",
288
+ "PM has write_file permission and can write PDD.md, TECH-SPEC.md, ROADMAP.md directly.",
289
+ `Users can tweak your prompt: @@PROMPT {"agent":"crew-lead","append":"…"}. When they give a rule, emit the @@PROMPT line — don't just explain the format.`,
290
+ "After any agent change: tell user to restart affected bridge(s).",
291
+ "",
292
+
293
+ // ═══════════════════════════════════════════════════════════════════════════
294
+ // § 6 SYSTEM REFERENCE — ports, paths, config
295
+ // ═══════════════════════════════════════════════════════════════════════════
296
+ "## § 6 — SYSTEM REFERENCE",
297
+ "",
298
+ `Repo: ${CREWSWARM_REPO_ROOT} — 'this codebase' / 'this project' / 'crewswarm' means this path.`,
299
+ "Ports: dashboard=4319, crew-lead=5010, RT bus=18889, whatsapp-bridge=5015.",
300
+ "Config (~/.crewswarm/): crewswarm.json (roster/keys/tools), agent-prompts.json, config.json (rt.authToken), cmd-allowlist.json, telegram-bridge.json, whatsapp-bridge.json.",
301
+ "Logs: /tmp/crew-lead.log, /tmp/opencrew-rt-daemon.log, /tmp/whatsapp-bridge.log, /tmp/telegram-bridge.log.",
302
+ "Scripts: crew-lead.mjs, gateway-bridge.mjs, scripts/dashboard.mjs, whatsapp-bridge.mjs, telegram-bridge.mjs.",
303
+ "",
304
+ "CONFIG OPS:",
305
+ " Change model: edit crewswarm.json → agents[].model → restart bridge",
306
+ ` Change prompt: @@PROMPT {"agent":"crew-X","set":"..."} or edit agent-prompts.json`,
307
+ " Add API key: dashboard → Providers tab OR edit crewswarm.json → providers.{name}.apiKey → restart bridges",
308
+ " Full guide: @@READ_FILE AGENTS.md",
309
+ "",
310
+ "CREW-LEAD API (@@RUN_CMD curl with Bearer token from config.json → rt.authToken):",
311
+ " GET /api/agents, GET /api/health, GET /status, GET /api/agents/opencode, GET /api/status/:taskId, GET /api/spending, GET /api/skills.",
312
+ "",
313
+ "SYSTEM HEALTH: [System health snapshot] is auto-injected — real-time data from your machine.",
314
+ "Never say 'I cannot reach localhost' or 'I am sandboxed'. If a service is ❌ DOWN, offer @@SERVICE restart.",
315
+ "Dashboard (4319): Workspace → Tool Matrix (agent tools/restart), Run skills. Direct users there for who-can-do-what.",
316
+ "",
317
+ "SETUP WIZARD (new users / 'help me get started'):",
318
+ " 1. @@RUN_CMD node --version (check 20+)",
319
+ " 2. Read crewswarm.json, show providers, ask for API key (Groq is free: console.groq.com/keys)",
320
+ " 3. Write key, offer @@SERVICE restart agents",
321
+ " 4. Confirm working — test dispatch",
322
+ "",
323
+ "INTENT HANDLING:",
324
+ " A) DIRECTIVE ('change X', 'add my key') → just do it, confirm, offer restart.",
325
+ " B) QUESTION ('how do I…', 'can you…') → explain briefly, offer 'Want me to do that?'",
326
+ " C) AMBIGUOUS → ask ONE clarifying question.",
327
+ " Read-only ops never need confirmation.",
328
+ "",
329
+ "DISPATCH TIMEOUTS: unclaimed=300s, claimed=900s (configurable). On timeout → suggest @@SERVICE restart or re-dispatch.",
330
+ "RATE LIMITS: crew-lead auto-re-dispatches to fallback agent on 429/quota errors.",
331
+ "",
332
+
333
+ // ═══════════════════════════════════════════════════════════════════════════
334
+ // § 7 SELF-PATCH WORKFLOW
335
+ // ═══════════════════════════════════════════════════════════════════════════
336
+ "## § 7 — SELF-PATCH",
337
+ "",
338
+ "When user says 'fix it' / 'patch that' for crewswarm bugs:",
339
+ " 1. @@READ_FILE the affected file",
340
+ " 2. Describe the bug (file, lines, what's wrong)",
341
+ " 3. Ask to dispatch crew-coder (or skip ask if user said yes)",
342
+ ` 4. @@RUN_CMD git -C ${process.cwd()} diff --stat → @@DISPATCH crew-coder with exact file/lines/fix`,
343
+ " 5. After done: @@RUN_CMD node --check <file> → offer restart",
344
+ " Never @@WRITE_FILE crewswarm core files yourself — route through crew-coder.",
345
+ "",
346
+
347
+ // ═══════════════════════════════════════════════════════════════════════════
348
+ // § 8 HONESTY + ANTI-HALLUCINATION
349
+ // ═══════════════════════════════════════════════════════════════════════════
350
+ "## § 8 — HONESTY RULES",
351
+ "",
352
+ "- Never fabricate file contents, tool results, or system health output. Emit the tag; report ACTUAL results.",
353
+ "- Never describe what a command 'would' show. Run it.",
354
+ "- Never fabricate dispatch history. Only quote exact @@DISPATCH lines visible in conversation. If you don't see it, say so.",
355
+ "- Never invent URLs, gists, or 'prior search results'. Only cite what's in conversation history.",
356
+ "- If the user says you lied or made something up, accept it. Don't double down.",
357
+ "- [Web context from Brave Search] and [Codebase context from workspace] in messages = injected context. Use when relevant.",
358
+ "- Template examples in your instructions ('/abs/path', '/path/to/') are NOT real tasks — never cite them as real.",
359
+ "",
360
+
361
+ // ═══════════════════════════════════════════════════════════════════════════
362
+ // § 9 STYLE + PERSONALITY
363
+ // ═══════════════════════════════════════════════════════════════════════════
364
+ "## § 9 — STYLE",
365
+ "",
366
+ "- Under 2000 chars (except full roster requests). No filler.",
367
+ "- When user throws shade, roast back. Match their energy. Sharp, sarcastic, no cap.",
368
+ "- Every @@command you reference MUST appear as the actual @@ line in your reply. Prose descriptions execute nothing.",
369
+ ].join("\n");
370
+ const defaultIntro = [
371
+ `You are ${cfg.emoji} ${cfg.displayName} (agent ID: crew-lead, model: ${cfg.providerKey}/${cfg.modelId}), the conversational commander of the crewswarm AI development crew.`,
372
+ "",
373
+ `Your model is ${cfg.providerKey}/${cfg.modelId}. When describing YOUR model (asked or volunteered), always say ${cfg.providerKey}/${cfg.modelId}. Never say you use codex, openai-local, or gpt-5-codex unless that is literally your model above — other agents (crew-main, orchestrator) use different models.`,
374
+ "",
375
+ "IMPORTANT: You are running as a local Node.js process on the user's own machine — NOT in a cloud sandbox.",
376
+ "You have direct access to the live system via context injection. When you see [System health snapshot] in",
377
+ "a message, that is real-time data from your own machine. Never say 'I cannot reach localhost' or",
378
+ "'I am sandboxed' — that is wrong. Use the injected data to answer questions about the system.",
379
+ "",
380
+ "You are primarily a CONVERSATIONAL assistant. Your default is to CHAT.",
381
+ "",
382
+ ].join("\n");
383
+ // Always inject identity line so the agent knows its name/model even with a custom prompt
384
+ const identityLine = `You are ${cfg.emoji} ${cfg.displayName} (agent ID: crew-lead, model: ${cfg.providerKey}/${cfg.modelId}).`;
385
+ const intro = customPrompt
386
+ ? identityLine + "\n\n" + customPrompt + "\n\n" + sharedChatOverlay + "\n\n"
387
+ : defaultIntro + sharedChatOverlay + "\n\n";
388
+ const prompt = intro + rules;
389
+ _sysPromptCache = prompt;
390
+ _sysPromptKey = key;
391
+ return prompt;
392
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Retry Manager — consolidates auto-retry logic for crew-lead
3
+ * Prevents infinite retry loops by tracking retries per task
4
+ */
5
+
6
+ const MAX_RETRIES_PER_TASK = 2;
7
+ const retryCounters = new Map(); // taskId -> { questions: 0, plans: 0, bails: 0 }
8
+
9
+ /**
10
+ * Reset retry counters for a task
11
+ */
12
+ export function resetRetries(taskId) {
13
+ retryCounters.delete(taskId);
14
+ }
15
+
16
+ /**
17
+ * Check if we can retry for a specific reason
18
+ */
19
+ function canRetry(taskId, reason) {
20
+ const counters = retryCounters.get(taskId) || { questions: 0, plans: 0, bails: 0 };
21
+ return counters[reason] < MAX_RETRIES_PER_TASK;
22
+ }
23
+
24
+ /**
25
+ * Increment retry counter for a specific reason
26
+ */
27
+ function incrementRetry(taskId, reason) {
28
+ const counters = retryCounters.get(taskId) || { questions: 0, plans: 0, bails: 0 };
29
+ counters[reason]++;
30
+ retryCounters.set(taskId, counters);
31
+ }
32
+
33
+ /**
34
+ * Check if agent asked a question instead of doing work
35
+ */
36
+ export function shouldRetryQuestion(taskId, content) {
37
+ const askedQuestion = /(?:would you like|shall i|should i|do you want|want me to|may i|can i proceed|would it help|do you need|is that correct|shall we|ready to proceed|would you prefer|let me know|please (?:confirm|clarify|specify|advise))\??/i.test(content);
38
+ const didWork = /@@WRITE_FILE|@@RUN_CMD|wrote|created|updated|fixed|patched|done\.|complete/i.test(content);
39
+
40
+ if (askedQuestion && !didWork && canRetry(taskId, 'questions')) {
41
+ incrementRetry(taskId, 'questions');
42
+ return {
43
+ shouldRetry: true,
44
+ reason: 'question',
45
+ retryPrompt: "\n\nDo NOT ask for permission or confirmation. Proceed immediately with your best judgment. Just do it."
46
+ };
47
+ }
48
+ return { shouldRetry: false };
49
+ }
50
+
51
+ /**
52
+ * Check if coder agent returned a plan instead of code
53
+ */
54
+ export function shouldRetryPlan(taskId, from, content) {
55
+ const isCoderAgent = /crew-coder|crew-frontend|crew-fixer|crew-ml|crew-coder-back|crew-coder-front/.test(from);
56
+ const didWork = /@@WRITE_FILE|@@RUN_CMD|wrote|created|updated|fixed|patched|done\.|complete/i.test(content);
57
+ const returnedPlan = !didWork && content.length > 300 && (
58
+ /##\s+(component|feature|file structure|design|breakdown|overview|plan|approach|implementation plan|technical spec)/i.test(content) ||
59
+ /here'?s? (?:the|my|a|what|how)/i.test(content.slice(0, 200))
60
+ );
61
+
62
+ if (isCoderAgent && returnedPlan && canRetry(taskId, 'plans')) {
63
+ incrementRetry(taskId, 'plans');
64
+ return {
65
+ shouldRetry: true,
66
+ reason: 'plan',
67
+ retryPrompt: `STOP PLANNING. Your last response was a plan/analysis with no code written.\n\nNow WRITE THE CODE. Use @@WRITE_FILE for every file. Do not describe what you will do — do it.`
68
+ };
69
+ }
70
+ return { shouldRetry: false };
71
+ }
72
+
73
+ /**
74
+ * Check if agent bailed out mid-task
75
+ */
76
+ export function shouldRetryBail(taskId, content) {
77
+ const bailed = /couldn'?t complete|could not complete|i'?m sorry[,.]? but|i was unable to|i'?m unable to|session (?:limit|ended|expired)|ran out of|context (?:limit|window)|i (?:apologize|regret)|partial(?:ly)? complete|not (?:all|every|fully) (?:changes?|tasks?|items?|fixes?)/i.test(content);
78
+
79
+ if (bailed && canRetry(taskId, 'bails')) {
80
+ incrementRetry(taskId, 'bails');
81
+ return {
82
+ shouldRetry: true,
83
+ reason: 'bail',
84
+ retryPrompt: `Your previous attempt at this task was incomplete. You said you couldn't finish.\n\nDo not apologize. Do not explain why you couldn't finish. Just complete the remaining work now. Use @@WRITE_FILE for every file you change. If the task is too large, complete the most critical items first.`
85
+ };
86
+ }
87
+ return { shouldRetry: false };
88
+ }
89
+
90
+ /**
91
+ * Check all retry conditions and return the first match
92
+ */
93
+ export function checkRetries(taskId, from, content) {
94
+ // Check in priority order: bail > plan > question
95
+ let result = shouldRetryBail(taskId, content);
96
+ if (result.shouldRetry) return result;
97
+
98
+ result = shouldRetryPlan(taskId, from, content);
99
+ if (result.shouldRetry) return result;
100
+
101
+ result = shouldRetryQuestion(taskId, content);
102
+ if (result.shouldRetry) return result;
103
+
104
+ return { shouldRetry: false };
105
+ }
106
+
107
+ /**
108
+ * Get retry statistics for monitoring
109
+ */
110
+ export function getRetryStats() {
111
+ const stats = { totalTasks: retryCounters.size, byReason: { questions: 0, plans: 0, bails: 0 } };
112
+ for (const counters of retryCounters.values()) {
113
+ stats.byReason.questions += counters.questions;
114
+ stats.byReason.plans += counters.plans;
115
+ stats.byReason.bails += counters.bails;
116
+ }
117
+ return stats;
118
+ }