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 @@
1
+ async function e(e,{ttl:t=0,bust:r=!1}={}){const s=await fetch(e);if(!s.ok)throw new Error(await s.text());return await s.json()}async function t(e,t,r){const s=await fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t),signal:r}),n=await s.text();if(!s.ok)throw new Error(n.slice(0,120));try{return JSON.parse(n)}catch{throw new Error("Bad response: "+n.slice(0,80))}}function r(e,t){return"online"===e?'<span title="● online — heartbeat <90s" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 5px var(--green);margin-right:4px;flex-shrink:0;"></span>':"stale"===e?'<span title="● stale — last seen >'+(t||"?")+'s ago" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:#f59e0b;margin-right:4px;flex-shrink:0;"></span>':"offline"===e?'<span title="● offline — no heartbeat in 5min" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--red-hi);margin-right:4px;flex-shrink:0;"></span>':'<span title="● unknown — never seen" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--text-3);margin-right:4px;flex-shrink:0;"></span>'}function s(e,t){e&&(e.innerHTML='<div class="meta" style="padding:20px;">'+(t||"Loading…")+"</div>")}function n(e,t){e&&(e.innerHTML='<div class="meta" style="padding:20px;">'+(t||"No items found.")+"</div>")}function a(e,t){e&&(e.innerHTML='<div class="meta" style="padding:20px;color:var(--red-hi);">'+(t||"An error occurred.")+"</div>")}function i(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function o(e,t){const r=document.createElement("div");r.className="notification"+("error"===t||!0===t?" error":"warning"===t?" warning":""),r.setAttribute("role","alert"),r.setAttribute("aria-live","polite"),r.textContent=e,document.body.appendChild(r),setTimeout(()=>r.remove(),4500)}function c(e){try{return new Date(e).toLocaleTimeString()}catch{return String(e)}}function l(e){return e&&e.time&&e.time.created||""}function d(e,t,r,s,n,a,i,o){const c=document.getElementById("chatMessages");if(!c)return;const l="user"===e,d=o&&"object"==typeof o&&!0===o.force;if(!l&&!d){const e=c.lastElementChild;if(e&&e.children.length>=2){if(e.children[1].textContent.trim()===String(t).trim())return}}const p=document.createElement("div");p.style.cssText="display:flex;flex-direction:column;align-items:"+(l?"flex-end":"flex-start")+";gap:4px;";const u=document.createElement("div");u.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;align-items:center;gap:6px;";const g=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"};if(i){let e="crew-lead";l?e="You":i.agentName?e=i.agentName:i.agent?e=i.agent:"cli"===i.source?e=i.engine||"cli":"sub-agent"===i.source?e="sub-agent":"agent"===i.source?e=i.targetAgent||"agent":"dashboard"===i.source&&(e="crew-lead");const t=!l&&i.engine&&i.engine!==e?` · ${i.engine}`:"";u.textContent=`${i.emoji||"🤖"} ${e}${t}`;const r=document.createElement("span");r.style.cssText="opacity:0.6;",r.textContent=i.timestamp?" · "+i.timestamp:"",u.appendChild(r)}else{const t=l?"You":"assistant"===e?g.emoji+" "+g.name:e;u.textContent=t}if(!l){const e=r||n;if(e){const t=document.createElement("span");r?(t.title="Primary failed ("+(s||"error")+") — running on fallback",t.style.cssText="font-size:10px;padding:1px 6px;border-radius:999px;background:rgba(245,158,11,0.15);color:#f59e0b;border:1px solid rgba(245,158,11,0.3);cursor:default;",t.textContent="⚡ fallback: "+r):(t.title="Primary model",t.style.cssText="font-size:10px;padding:1px 6px;border-radius:999px;background:rgba(52,211,153,0.1);color:#34d399;border:1px solid rgba(52,211,153,0.2);cursor:default;",t.textContent=e),u.appendChild(t)}if(a){const e={claude:"#e07a5f",codex:"#8338ec",cursor:"#3d405b",opencode:"#06d6a0",gemini:"#4285f4","docker-sandbox":"#0db7ed"},t={claude:"🤖 Claude Code",codex:"🟣 Codex",cursor:"🖱 Cursor",opencode:"⚡ OpenCode",gemini:"✨ Gemini","docker-sandbox":"🐳 Docker"},r=document.createElement("span");r.title="Executed by "+(t[a]||a),r.style.cssText="font-size:10px;padding:1px 6px;border-radius:999px;color:#fff;background:"+(e[a]||"var(--text-3)")+";cursor:default;",r.textContent=t[a]||a,u.appendChild(r)}}const h=document.createElement("div");h.style.cssText="max-width:80%;padding:10px 14px;border-radius:"+(l?"14px 14px 4px 14px":"14px 14px 14px 4px")+";background:"+(l?"var(--purple)":"var(--surface-2)")+";color:"+(l?"#fff":"var(--text-2)")+";font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid var(--border);",h.textContent=t,p.appendChild(u),p.appendChild(h),c.appendChild(p),c.scrollTop=c.scrollHeight}const p="crewswarm_ui_state";const u=function(){try{const e=sessionStorage.getItem(p);return e?JSON.parse(e):{}}catch{return{}}}(),g={selected:u.selected||null,selectedEngine:u.selectedEngine||"opencode",agents:u.agents||[],chatActiveProjectId:u.chatActiveProjectId||"",swarmChatProjectId:u.swarmChatProjectId||"",projectsData:u.projectsData||{},activeTab:u.activeTab||"chat",scrollPositions:u.scrollPositions||{}};function h(){try{sessionStorage.setItem(p,JSON.stringify({selected:g.selected,selectedEngine:g.selectedEngine,chatActiveProjectId:g.chatActiveProjectId,swarmChatProjectId:g.swarmChatProjectId,projectsData:g.projectsData,activeTab:g.activeTab,scrollPositions:g.scrollPositions}))}catch{}}function f(e){const t=document.querySelector(".view.active");t&&(g.scrollPositions[e||g.activeTab]=t.scrollTop,h())}function x(e){const t=g.scrollPositions[e];null!=t&&requestAnimationFrame(()=>{const e=document.querySelector(".view.active");e&&(e.scrollTop=t)})}const m={"crew-lead":0,"crew-orchestrator":1,orchestrator:1,"crew-main":2,"crew-pm":3,"crew-architect":4,"crew-coder":5,"crew-coder-back":6,"crew-coder-front":7,"crew-frontend":8,"crew-ml":9,"crew-fixer":10,"crew-qa":11,"crew-security":12,"crew-researcher":13,"crew-copywriter":14,"crew-seo":15,"crew-github":16,"crew-db-migrator":17,"crew-telegram":18,"crew-mega":19};function w(e){return(e||[]).sort((e,t)=>(m[e.id]??50)-(m[t.id]??50))}const b=new class{constructor(){this.activeTasks=new Map,this.listeners=new Set}registerTask(e,t){this.activeTasks.set(e,{...t,startTime:Date.now(),status:"running"}),this.notifyListeners()}stopTask(e){const t=this.activeTasks.get(e);return!!t&&(t.controller&&t.controller.abort(),t.status="stopped",this.activeTasks.delete(e),this.notifyListeners(),!0)}completeTask(e){const t=this.activeTasks.get(e);t&&(t.status="completed",this.activeTasks.delete(e),this.notifyListeners())}failTask(e,t){const r=this.activeTasks.get(e);r&&(r.status="failed",r.error=t,this.activeTasks.delete(e),this.notifyListeners())}getActiveTasks(){return Array.from(this.activeTasks.entries()).map(([e,t])=>({id:e,...t}))}isAgentBusy(e){return Array.from(this.activeTasks.values()).some(t=>t.agent===e&&"running"===t.status)}stopAll(){for(const[e]of this.activeTasks)this.stopTask(e)}stopAgent(e){for(const[t,r]of this.activeTasks)r.agent===e&&this.stopTask(t)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notifyListeners(){for(const t of this.listeners)try{t(this.getActiveTasks())}catch(e){console.error("TaskManager listener error:",e)}}};export{g as a,h as b,n as c,a as d,i as e,w as f,e as g,x as h,c as i,l as j,s as k,f as l,d as m,t as p,r,o as s,b as t};
@@ -0,0 +1 @@
1
+ :root{--bg: #060a10;--bg-0: #040810;--bg-1: #0d1420;--bg-2: #111827;--bg-card: #0d1420;--bg-card2: #111827;--bg-hover: #141e2e;--surface-2: #16202e;--border: rgba(255, 255, 255, .07);--border-hi: rgba(56, 189, 248, .35);--text: #f0f6ff;--text-1: #f0f6ff;--text-2: #a0b3cc;--text-3: #7a8a9f;--accent: #38bdf8;--accent2: #818cf8;--purple: #818cf8;--green: #34d399;--red: #f87171;--yellow: #fbbf24;--amber: #f59e0b;--green-hi: #22c55e;--red-hi: #ef4444;--sky: #38bdf8;--blue: #4a7ab5;--teal: #0f766e;--warning: #f59e0b;--radius: 10px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,sans-serif;background:var(--bg);color:var(--text);display:flex;height:100vh;overflow:hidden;font-size:14px;touch-action:manipulation}.skip-link{position:absolute;top:-40px;left:0;background:var(--accent);color:#000;padding:8px 16px;text-decoration:none;font-weight:600;border-radius:0 0 4px;z-index:9999}.skip-link:focus{top:0}*:focus-visible{outline:3px solid var(--accent);outline-offset:2px}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--accent);outline-offset:2px}.sidebar{width:216px;min-width:216px;background:var(--bg-card);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow-y:auto}.sidebar-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px;border-bottom:1px solid var(--border);text-decoration:none}.brand-icon{width:24px;height:24px;object-fit:contain;display:block}.brand-name{font-size:15px;font-weight:800;color:var(--text);letter-spacing:.06em;text-transform:uppercase}.brand-name span{color:var(--accent)}.sidebar-status{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--border)}.status-dot{width:7px;height:7px;border-radius:50%;background:var(--text-3);flex-shrink:0}.status-dot.online{background:var(--green);box-shadow:0 0 6px var(--green)}.status-dot.error{background:var(--red)}#status{font-size:12px;color:var(--text-2)}.nav-section{padding:12px 8px 4px}.nav-label{font-size:10px;font-weight:600;color:var(--text-3);letter-spacing:.08em;text-transform:uppercase;padding:0 8px 6px}.nav-item{display:flex;align-items:center;gap:9px;width:100%;padding:8px 10px;border-radius:7px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;text-align:left;transition:background .12s,color .12s;font-family:inherit}.stab{padding:7px 16px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;font-family:inherit;transition:color .12s,border-color .12s;white-space:nowrap}.stab:hover{color:var(--text-1)}.stab.active{color:var(--accent);border-bottom-color:var(--accent)}.nav-item:hover{background:var(--bg-hover);color:var(--text)}.nav-item.active{background:#38bdf81a;color:var(--accent)}.nav-item .nav-icon{font-size:15px;width:18px;text-align:center}.nav-badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:999px;min-width:18px;text-align:center}.nav-badge.hidden{display:none}.sidebar-bottom{margin-top:auto;padding:12px 8px;border-top:1px solid var(--border)}.main-wrap{flex:1;display:flex;flex-direction:column;overflow:hidden}.view{display:none;flex:1;overflow-y:auto;padding:24px}.view.active{display:block}.view-sessions{display:none;flex:1;overflow:hidden}.view-sessions.active{display:grid;grid-template-columns:34% 66%}.view-sessions>section{padding:16px;overflow-y:auto}.view-sessions>section+section{border-left:1px solid var(--border)}.msg-bar{padding:10px 16px;border-top:1px solid var(--border);background:var(--bg-card);display:flex;gap:8px;align-items:center;flex-shrink:0}.card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;margin-bottom:12px}.card-title{font-size:15px;font-weight:600;margin-bottom:4px}.status-badge{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;letter-spacing:.02em}.status-active,.status-running{background:#22c55e26;color:var(--green-hi);border:1px solid rgba(34,197,94,.3)}.status-stopped{background:#ef44441f;color:var(--red-hi);border:1px solid rgba(239,68,68,.25)}.meta{font-size:12px;color:var(--text-2)}.page-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:20px}.page-title{font-size:18px;font-weight:700;letter-spacing:-.3px}.page-sub{font-size:13px;color:var(--text-2);margin-top:3px}h3{font-size:14px;font-weight:600;margin-bottom:8px}.msg{border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;margin-bottom:8px;background:var(--bg-card)}.msg.u{border-left:3px solid var(--accent);background:#38bdf812;margin-left:40px}.msg.a{border-left:3px solid var(--green);background:#34d3990a}.dlq-item{border-left:3px solid var(--red)!important}.t{white-space:pre-wrap;font-size:13px;line-height:1.5;font-family:SF Mono,Fira Code,monospace}.chat-bubble{background:var(--surface-2);border-radius:10px;padding:12px 14px;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;max-width:85%;will-change:contents;contain:layout style paint}.chat-bubble.user{background:#38bdf81a;border:1px solid rgba(56,189,248,.2);margin-left:auto}.chat-bubble.assistant{background:var(--bg-card);border:1px solid var(--border)}#chatProjectTabs{scrollbar-width:thin;scrollbar-color:var(--border) transparent}#chatProjectTabs::-webkit-scrollbar{height:4px}#chatProjectTabs::-webkit-scrollbar-track{background:transparent}#chatProjectTabs::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}.project-tab{padding:6px 14px;border-radius:6px;font-size:12px;white-space:nowrap;cursor:pointer;border:none;background:#ffffff0a;color:var(--text-2);font-weight:500;transition:all .2s;font-family:inherit}.project-tab:hover{background:#ffffff14}.project-tab.active{background:var(--accent);color:var(--bg);font-weight:600}.row{padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;cursor:pointer;background:var(--bg-card);transition:border-color .12s,background .12s}.row:hover{background:var(--bg-hover)}.row.active{border-color:var(--accent);background:#38bdf80f}button{background:var(--accent);color:#000;border:none;border-radius:7px;padding:7px 14px;cursor:pointer;font-weight:600;font-size:13px;font-family:inherit;transition:opacity .12s}button:hover{opacity:.85}.btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border)}.btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.btn-green{background:var(--green);color:#000}.btn-sky{background:#0ea5e9;color:#000;border:1px solid #0ea5e9}.btn-sky:hover{background:var(--accent)}.btn-red{background:var(--red);color:#fff}.btn-yellow{background:var(--yellow);color:#000}.btn-purple{background:var(--accent2);color:#fff}.btn-muted{background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.reply-btn{font-size:11px;padding:3px 8px;background:var(--accent2);color:#fff;margin-left:8px}.replay-btn{font-size:11px;padding:3px 8px;background:var(--yellow);color:#000;margin-left:8px}.send-btn{background:var(--green);color:#000}.emoji-btn{width:46px;height:46px;font-size:22px;background:#ffffff0a;border:1px solid rgba(255,255,255,.1);border-radius:var(--radius);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .15s,background .15s;color:inherit}.emoji-btn:hover{border-color:var(--accent);background:#38bdf814}.emoji-picker-wrap{position:relative;flex-shrink:0}.emoji-picker-panel{display:none;position:absolute;top:50px;right:0;z-index:200;background:var(--bg-card);border:1px solid var(--border-hi);border-radius:var(--radius);padding:10px;box-shadow:0 8px 32px #00000080;width:260px}.emoji-picker-panel.open{display:block}.emoji-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:6px}.emoji-opt{font-size:22px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:6px;transition:background .1s}.emoji-opt:hover{background:#38bdf826}.file-row{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px;transition:border-color .15s}.file-row:hover{border-color:var(--accent)}.file-info{flex:1;min-width:0}.file-name{display:block;font-size:13px;color:var(--text);font-family:SF Mono,Fira Code,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-meta{font-size:11px;color:var(--text-2)}.file-actions{display:flex;gap:5px;flex-shrink:0}.file-btn{font-size:11px;padding:3px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-card2);color:var(--text-2);cursor:pointer;text-decoration:none;transition:all .15s;white-space:nowrap}.file-btn:hover{color:var(--text);border-color:var(--accent)}.file-btn-cursor{border-color:#6366f166;color:#818cf8}.file-btn-cursor:hover{background:#6366f126}.file-btn-opencode{border-color:#34d39966;color:#34d399}.file-btn-opencode:hover{background:#34d3991a}select,input[type=text],input[type=password],input[type=number],input[type=email],input:not([type]),textarea{background:var(--bg-1);color:var(--text-1);border:1px solid var(--border);border-radius:6px;padding:6px 10px;font-size:13px;font-family:inherit;outline:none;transition:border-color .15s,background .15s,box-shadow .15s;width:100%;box-sizing:border-box}select:focus,input:not([type]):focus,input[type=text]:focus,input[type=password]:focus,input[type=number]:focus,input[type=email]:focus,textarea:focus{border-color:var(--accent);background:#38bdf80a;box-shadow:0 0 0 3px #38bdf814}select{cursor:pointer}::placeholder{color:var(--text-3);opacity:1}input[type=text]{flex:1}textarea{resize:vertical;width:100%}input,textarea,select{user-select:text;-webkit-user-select:text;cursor:text}.inp-sm{padding:5px 8px!important;font-size:12px!important}.inp-xs{padding:3px 6px!important;font-size:12px!important;width:auto!important}.inp-mono{font-family:SF Mono,Fira Code,ui-monospace,monospace!important}.inp-flex{flex:1;width:auto!important}.notification{position:fixed;top:20px;right:20px;background:var(--green);color:#000;padding:12px 20px;border-radius:8px;box-shadow:0 4px 20px #0006;z-index:1000;animation:slideIn .25s ease;font-weight:600;font-size:13px}.notification.error{background:var(--red);color:#fff}.notification.warning{background:var(--amber);color:#000}@keyframes slideIn{0%{transform:translate(120%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes pulse{0%,to{opacity:.3;transform:scale(.85)}50%{opacity:1;transform:scale(1.15)}}.log-block{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:12px;font-family:SF Mono,Fira Code,monospace;font-size:12px;color:var(--accent);max-height:220px;overflow-y:auto;white-space:pre-wrap;line-height:1.5}.rm-textarea{width:100%;font-family:SF Mono,Fira Code,monospace;font-size:12px;background:var(--bg);color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:12px;line-height:1.6;resize:vertical;box-sizing:border-box}.log-block.green{color:var(--green);border-color:#34d39933}.log-block.mono{color:var(--text-2)}.provider-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-bottom:10px}.provider-header{display:flex;align-items:center;gap:12px;padding:13px 16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .12s}.provider-header:hover{background:var(--bg-hover)}.provider-badge{font-size:11px;padding:2px 8px;border-radius:999px;font-weight:600}.provider-body{display:none;padding:16px;border-top:1px solid var(--border);background:var(--bg)}.provider-body.open{display:block}.key-row{display:flex;gap:8px;align-items:center;margin-bottom:12px}.key-input{flex:1;font-family:SF Mono,Fira Code,ui-monospace,monospace}.model-tag{display:inline-block;background:var(--bg-card2);border:1px solid var(--border);border-radius:5px;padding:2px 8px;font-size:11px;margin:2px;font-family:SF Mono,monospace;color:var(--text-2)}.test-ok{color:var(--green);font-size:12px;margin-left:8px;font-weight:600}.test-err{color:var(--red);font-size:12px;margin-left:8px}.pm-badge{font-size:11px;padding:2px 10px;border-radius:999px;font-weight:600;margin-left:10px;background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.pm-badge.running{background:#34d3991a;color:var(--green);border-color:#34d3994d}.prog-bar{height:4px;background:var(--bg-card2);border-radius:2px;overflow:hidden;margin:8px 0}.prog-fill{height:100%;border-radius:2px;transition:width .3s}.divider{border:none;border-top:1px solid var(--border);margin:20px 0}.agent-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.agent-card-header{display:flex;align-items:center;gap:12px;padding:14px 16px}.agent-avatar{width:38px;height:38px;border-radius:10px;background:var(--bg-card2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}.agent-meta{flex:1;min-width:0}.agent-id{font-weight:700;font-size:14px}.agent-model{font-size:12px;color:var(--text-2);font-family:SF Mono,monospace;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-body{border-top:1px solid var(--border);padding:14px 16px;background:var(--bg);display:grid;gap:12px}.agent-row{display:grid;grid-template-columns:110px 1fr auto auto;gap:8px;align-items:center}.agent-row label{font-size:12px;color:var(--text-2);font-weight:500}.agent-badge{font-size:11px;padding:2px 8px;border-radius:999px;background:#38bdf81a;color:var(--accent);border:1px solid rgba(56,189,248,.2);font-weight:600}.agent-badge.online{background:#34d3991a;color:var(--green);border-color:#34d3994d}.field-label{font-size:11px;font-weight:600;color:var(--text-2);margin-bottom:5px;text-transform:uppercase;letter-spacing:.05em}.tool-profile-opt{cursor:pointer}.tool-profile-opt input[type=radio]{display:none}.tp-card{border:1px solid var(--border);border-radius:8px;padding:10px 12px;transition:border-color .12s,background .12s}.tool-profile-opt:hover .tp-card{border-color:var(--accent);background:var(--bg-hover)}.tool-profile-opt input:checked+.tp-card{border-color:var(--accent);background:#38bdf812}.tp-name{font-size:13px;font-weight:700;margin-bottom:4px;color:var(--text);font-family:SF Mono,monospace}.tp-desc{font-size:11px;color:var(--text-2);line-height:1.4}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}#rtView::-webkit-scrollbar{width:8px}#rtView::-webkit-scrollbar-track{background:var(--bg-card);border-radius:4px}#rtView::-webkit-scrollbar-thumb{background:var(--accent);border-radius:4px;opacity:.7}#rtView::-webkit-scrollbar-thumb:hover{background:var(--accent);opacity:1}#rtView{scrollbar-width:thin;scrollbar-color:var(--accent) var(--bg-card)}@media(max-width:1100px){body{flex-direction:column}.sidebar{width:100%!important;min-width:0!important;flex-direction:row;flex-wrap:wrap;padding:8px 12px;gap:4px;border-right:none;border-bottom:1px solid var(--border)}.sidebar .nav-item{padding:6px 10px;font-size:12px}.sidebar .nav-section{display:flex;flex-wrap:wrap;padding:0;gap:4px}.sidebar .nav-label,.sidebar .sidebar-bottom{display:none}.main-wrap{min-width:0}}@media(max-width:768px){.sidebar .nav-label{display:none}.sidebar .nav-item{padding:8px;min-width:36px;justify-content:center}#servicesGrid,#agentsList,#projectsList,#runSkillsGrid{grid-template-columns:1fr!important}.chat-input-row{flex-wrap:wrap;gap:6px}.chat-input-row button{height:44px}#chatInput{min-height:44px}.page-header{flex-direction:column;align-items:flex-start;gap:8px}.page-header .actions{flex-wrap:wrap}.container,.dashboard-grid,.view,.card{width:100%;max-width:100%;padding:1rem}img,video{max-width:100%;height:auto}button,a,.nav-item,input,select,textarea{min-height:44px}}@media(max-width:480px){body{font-size:13px}.card{padding:12px}.card-title{font-size:14px}.page-title{font-size:18px}.tab-bar{flex-wrap:wrap;gap:4px}.stab{padding:4px 10px;font-size:11px}button{min-height:44px;font-size:16px;padding:8px 16px}input,select,textarea{font-size:16px;min-height:44px}input:focus,select:focus,textarea:focus{font-size:16px}}.prompt-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;transition:all .2s}.prompt-card:hover{border-color:var(--border-hi);background:var(--bg-hover)}.prompt-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;gap:12px}.prompt-preview{font-size:12px;color:var(--text-2);line-height:1.5;font-family:SF Mono,Monaco,monospace;white-space:pre-wrap;word-break:break-word}.prompt-edit-btn{flex-shrink:0}.agent-info-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:16px}.agent-info-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.agent-info-header h4{margin:0;font-size:16px;font-weight:600}.agent-status{padding:4px 10px;border-radius:12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.agent-status.active{background:var(--green-hi);color:#000}.agent-status.idle{background:var(--bg-card2);color:var(--text-3)}.agent-info-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:13px;align-items:center}.detail-row .label{color:var(--text-3);font-weight:600}.detail-row .value{color:var(--text-1);font-family:SF Mono,Monaco,monospace;font-size:12px}#agentChatMessages{display:flex;flex-direction:column;gap:12px}.user-message,.agent-message{padding:12px 16px;border-radius:12px;max-width:75%;word-wrap:break-word}.user-message{background:var(--accent);color:#fff;align-self:flex-end;border-bottom-right-radius:4px}.agent-message{background:var(--bg-card);border:1px solid var(--border);align-self:flex-start;border-bottom-left-radius:4px}.message-header{display:flex;justify-content:space-between;margin-bottom:6px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;opacity:.8}.message-time{color:var(--text-3);font-size:10px;font-weight:400;text-transform:none;letter-spacing:0}.message-content{font-size:14px;line-height:1.6}.message-content code{background:#0000004d;padding:2px 6px;border-radius:4px;font-family:SF Mono,Monaco,monospace;font-size:13px}.message-content pre{background:#0006;padding:12px;border-radius:6px;overflow-x:auto;margin:8px 0;border:1px solid var(--border)}.message-content pre code{background:none;padding:0}.message-content a{color:var(--accent);text-decoration:none}.message-content a:hover{text-decoration:underline}.process-card{background:var(--bg-card);padding:12px;border-radius:8px;margin-bottom:8px}.process-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.process-cli{font-weight:600;font-family:SF Mono,Monaco,monospace;font-size:13px}.process-status{text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);letter-spacing:.05em}.process-details{font-size:12px;color:var(--text-2);line-height:1.6;font-family:SF Mono,Monaco,monospace}.empty-state{text-align:center;padding:60px 20px;color:var(--text-3);font-size:14px}.process-status-empty{padding:12px;text-align:center;color:var(--text-3);font-size:12px;font-style:italic}#workflowsLayout{display:grid;grid-template-columns:minmax(260px,340px) minmax(420px,1fr);gap:16px;align-items:start}@media(max-width:980px){#workflowsLayout{grid-template-columns:1fr}}.setup-wizard-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#040810eb;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);opacity:0;transition:opacity .26s ease}.setup-wizard-overlay.visible{opacity:1}.setup-wizard-overlay.dismissing{opacity:0}.setup-wizard-card{width:100%;max-width:520px;margin:0 16px;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:40px 36px 32px;box-shadow:0 0 0 1px #ffffff0a,0 24px 64px #00000080;transform:translateY(12px) scale(.98);opacity:0;transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s ease}.setup-wizard-card.visible{transform:translateY(0) scale(1);opacity:1}.setup-wizard-steps{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:32px}.setup-wizard-step{display:flex;flex-direction:column;align-items:center;gap:6px}.setup-wizard-step-dot{width:10px;height:10px;border-radius:50%;border:2px solid var(--text-3);background:transparent;padding:0;cursor:default;transition:background .2s ease,border-color .2s ease,box-shadow .2s ease}.setup-wizard-step-dot.active{border-color:var(--accent);background:var(--accent);box-shadow:0 0 8px #38bdf866}.setup-wizard-step-dot.completed{border-color:var(--green);background:var(--green)}.setup-wizard-step-label{font-size:11px;color:var(--text-3);font-weight:500;letter-spacing:.02em}.setup-wizard-step .active~.setup-wizard-step-label,.setup-wizard-step-dot.active+.setup-wizard-step-label{color:var(--accent)}.setup-wizard-step-dot.completed+.setup-wizard-step-label{color:var(--green)}.setup-wizard-step-line{width:48px;height:2px;background:var(--text-3);margin:0 12px 18px;border-radius:1px;transition:background .2s ease}.setup-wizard-step-line.completed{background:var(--green)}.setup-wizard-content{display:flex;flex-direction:column}.setup-wizard-hero{text-align:center;margin-bottom:28px}.setup-wizard-logo-ring{display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:16px;background:var(--bg-card2);border:1px solid var(--border);margin-bottom:20px}.setup-wizard-logo{width:36px;height:36px}.setup-wizard-title{font-size:24px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:8px;letter-spacing:-.02em}.setup-wizard-subtitle{font-size:15px;color:var(--text-2);line-height:1.5}.setup-wizard-checklist{display:flex;flex-direction:column;gap:10px;padding:16px 20px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;margin-bottom:28px}.setup-wizard-check-item{display:flex;align-items:center;gap:10px;font-size:14px;color:var(--text-2)}.setup-wizard-check-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:12px;flex-shrink:0}.setup-wizard-check-icon.done{background:#34d39926;color:var(--green);border:1px solid rgba(52,211,153,.3)}.setup-wizard-check-icon.pending{background:var(--bg-card);color:var(--text-3);border:1px solid var(--border);font-size:8px}.setup-wizard-section-header{margin-bottom:20px}.setup-wizard-section-title{font-size:20px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-section-desc{font-size:14px;color:var(--text-2);line-height:1.5}.setup-wizard-provider-list{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;max-height:360px;overflow-y:auto}.setup-wizard-provider-row{display:flex;flex-direction:column;gap:6px;padding:12px 14px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;transition:border-color .2s ease,background .2s ease}.setup-wizard-provider-row.has-key{border-color:#34d3994d;background:#34d3990a}.setup-wizard-provider-label{display:flex;align-items:center;gap:8px}.setup-wizard-provider-icon{font-size:16px;width:22px;text-align:center;flex-shrink:0}.setup-wizard-provider-name{font-size:14px;font-weight:600;color:var(--text)}.setup-wizard-provider-link{margin-left:auto;font-size:12px;color:var(--accent);text-decoration:none;opacity:.7;transition:opacity .15s ease}.setup-wizard-provider-link:hover{opacity:1;text-decoration:underline}.setup-wizard-provider-input-wrap{display:flex;align-items:center;gap:6px}.setup-wizard-provider-input{flex:1;background:var(--bg);border:1px solid var(--border);border-radius:7px;padding:8px 10px;color:var(--text);font-size:13px;font-family:inherit;outline:none;transition:border-color .2s ease}.setup-wizard-provider-input::placeholder{color:var(--text-3)}.setup-wizard-provider-input:focus{border-color:var(--accent)}.setup-wizard-toggle-vis{background:transparent;border:1px solid var(--border);border-radius:6px;padding:6px 8px;font-size:14px;cursor:pointer;color:var(--text-3);transition:color .15s ease}.setup-wizard-toggle-vis:hover{color:var(--text)}.setup-wizard-engine-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-bottom:16px}.setup-wizard-engine-card{background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:6px;transition:border-color .15s ease,background .15s ease}.setup-wizard-engine-card.available{border-color:#34d3994d;background:#34d39908}.setup-wizard-engine-card:not(.available){opacity:.7}.setup-wizard-engine-badge{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.setup-wizard-engine-badge.installed{color:var(--green, #34d399)}.setup-wizard-engine-badge.missing{color:var(--text-3, #666)}.setup-wizard-engine-title{font-size:15px;font-weight:600;color:var(--text)}.setup-wizard-engine-cmd{font-size:12px;color:var(--text-3);background:var(--bg-card);padding:2px 8px;border-radius:4px;display:inline-block;width:fit-content;font-family:var(--font-mono, monospace)}.setup-wizard-engine-desc{font-size:12px;color:var(--text-2);line-height:1.4;margin:4px 0 8px}.setup-wizard-engine-action{margin-top:auto;display:flex;align-items:center;gap:6px;font-size:12px}.setup-wizard-engine-auth-label{color:var(--text-3)}.setup-wizard-engine-auth-cmd{font-size:11px;color:var(--accent);background:#6366f11a;padding:3px 8px;border-radius:4px;font-family:var(--font-mono, monospace)}.setup-wizard-engine-key-note{font-size:12px}.setup-wizard-engine-key-note.key-ok{color:var(--green, #34d399)}.setup-wizard-engine-key-note.key-missing{color:var(--yellow, #fbbf24)}.setup-wizard-engine-install-btn{font-size:12px;color:var(--accent);text-decoration:none;font-weight:500;padding:4px 12px;border:1px solid var(--accent);border-radius:6px;transition:background .15s ease}.setup-wizard-engine-install-btn:hover{background:#6366f11a}.setup-wizard-engine-hint{font-size:13px;color:var(--text-2);text-align:center;margin:8px 0}.setup-wizard-provider-icon{font-size:16px;width:24px;text-align:center;flex-shrink:0}.setup-wizard-preset-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:24px}.setup-wizard-preset-card{display:flex;flex-direction:column;align-items:center;text-align:center;padding:20px 12px;background:var(--bg-card2);border:2px solid var(--border);border-radius:12px;cursor:pointer;transition:border-color .2s ease,background .2s ease,transform .15s ease}.setup-wizard-preset-card:hover{background:var(--bg-hover);transform:translateY(-1px)}.setup-wizard-preset-card.selected{border-color:var(--accent);background:#38bdf80f}.setup-wizard-preset-icon{font-size:28px;margin-bottom:10px;line-height:1}.setup-wizard-preset-label{font-size:15px;font-weight:700;color:var(--text);margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-preset-desc{font-size:12px;color:var(--text-2);line-height:1.4}.setup-wizard-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:8px}.setup-wizard-btn-primary{background:var(--accent);color:#000;border:none;border-radius:8px;padding:10px 24px;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;transition:opacity .15s ease,transform .1s ease}.setup-wizard-btn-primary:hover{opacity:.9}.setup-wizard-btn-primary:active{transform:scale(.98)}.setup-wizard-btn-primary:disabled{opacity:.4;cursor:not-allowed}.setup-wizard-btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:10px 20px;font-size:14px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease}.setup-wizard-btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.setup-wizard-error{padding:10px 14px;background:#f871711a;border:1px solid rgba(248,113,113,.25);border-radius:8px;color:var(--red);font-size:13px;margin-bottom:12px}.setup-wizard-error.hidden{display:none}@media(max-width:640px){.setup-wizard-card{padding:28px 20px 24px;margin:0 12px;border-radius:12px}.setup-wizard-engine-grid,.setup-wizard-preset-grid{grid-template-columns:1fr;gap:8px}.setup-wizard-preset-card{flex-direction:row;text-align:left;gap:12px;padding:14px 16px}.setup-wizard-preset-icon{font-size:22px;margin-bottom:0}.setup-wizard-preset-label{margin-bottom:2px}.setup-wizard-step-line{width:28px;margin:0 6px}.setup-wizard-actions{flex-direction:column-reverse}.setup-wizard-btn-primary,.setup-wizard-btn-ghost{width:100%;text-align:center}}
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tab-benchmarks-tab-DfCuAClu.js","assets/core-utils-CAVnDoe1.js"])))=>i.map(i=>d[i]);
2
+ var e,t,n;import{a as o,g as a,b as s,s as i,p as r,d as l,c,k as d,r as p,h as m,l as u,m as g,e as h}from"./core-utils-CAVnDoe1.js";import{c as v}from"./setup-wizard-i3eEixlo.js";import{i as f}from"./components-CSUb80ze.js";import{s as y}from"./orchestration-Ca2DLWN-.js";import"./cli-process-COMRNPqr.js";import{i as w}from"./chat-core-BwSoInmZ.js";import{i as b,s as x,h as k}from"./tab-swarm-chat-tab-BBV9HB2X.js";import{i as C}from"./tab-waves-tab-SaJDkb4x.js";import{i as E,s as I}from"./tab-workflows-tab-6QSXLJ0i.js";import{c as T,m as B,s as S,l as j,a as A}from"./tab-memory-tab-C59BYFQD.js";import{i as P,s as L,l as M,a as _,r as N}from"./tab-services-tab-DBj_w3bc.js";import{i as R,s as O,l as F,a as H,t as D,b as z,c as G,d as $,e as V,f as q,g as K,h as U,j as W,k as J,m as Q,n as Y,o as X,p as Z,r as ee,q as te,u as ne,v as oe,w as ae,x as se,y as ie,z as re,A as le}from"./tab-agents-tab-BThdsdJY.js";import{i as ce,a as de}from"./tab-prompts-tab-C0wZvWK3.js";import{s as pe,a as me,l as ue,c as ge,b as he,i as ve,t as fe,d as ye,f as we,r as be,e as xe,g as ke,u as Ce}from"./tab-skills-tab-BYdU2whk.js";import{s as Ee,i as Ie,a as Te,l as Be}from"./tab-contacts-tab-yEegNyO4.js";import{i as Se,t as je,l as Ae,d as Pe}from"./tab-engines-tab-C3DYxTwy.js";import{s as Le,a as Me,b as _e,c as Ne,t as Re,d as Oe,r as Fe,i as He}from"./tab-swarm-tab-ChqLlEVs.js";import{i as De,s as ze,t as Ge,a as $e,b as Ve,c as qe,d as Ke,e as Ue,f as We,g as Je,h as Qe,j as Ye}from"./tab-models-tab-9Ur7pXWA.js";import{s as Xe,a as Ze,b as et,t as tt,c as nt,d as ot,e as at,f as st,g as it,h as rt,i as lt,j as ct,k as dt,l as pt,u as mt,m as ut,n as gt,o as ht,p as vt,q as ft,r as yt,v as wt,w as bt,x as xt,y as kt,z as Ct,A as Et,B as It,C as Tt,D as Bt,E as St,F as jt,G as At,H as Pt}from"./tab-settings-tab-ezeqAjZk.js";import{i as Lt,s as Mt,l as _t,a as Nt,b as Rt,c as Ot,d as Ft,e as Ht,f as Dt,g as zt,h as Gt,r as $t,j as Vt}from"./tab-comms-tab-eHpOSBhG.js";import{i as qt,p as Kt,r as Ut,c as Wt,a as Jt,b as Qt,e as Yt,d as Xt,l as Zt,o as en,f as tn,h as nn,j as on,k as an,m as sn,n as rn,q as ln,t as cn,v as dn,w as pn}from"./tab-projects-tab-C6h2Mv1K.js";import{a as mn,r as un,c as gn,b as hn,l as vn,d as fn}from"./tab-usage-tab-B2UWXenJ.js";import{s as yn,r as wn,l as bn,a as xn,b as kn}from"./tab-spending-tab-Bg6w9t_p.js";import{i as Cn}from"./tab-pm-loop-tab-D7mnDelU.js";!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of n.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const En={};let In=null;async function Tn(){return In||(In=await function(e,t){let n=Promise.resolve();if(t&&t.length>0){let e=function(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:"fulfilled",value:e}),e=>({status:"rejected",reason:e}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),a=(null==o?void 0:o.nonce)||(null==o?void 0:o.getAttribute("nonce"));n=e(t.map(e=>{if((e=function(e){return"/"+e}(e))in En)return;En[e]=!0;const t=e.endsWith(".css"),n=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${n}`))return;const o=document.createElement("link");return o.rel=t?"stylesheet":"modulepreload",t||(o.as="script"),o.crossOrigin="",o.href=e,a&&o.setAttribute("nonce",a),document.head.appendChild(o),t?new Promise((t,n)=>{o.addEventListener("load",t),o.addEventListener("error",()=>n(new Error(`Unable to preload CSS for ${e}`)))}):void 0}))}function o(e){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return n.then(t=>{for(const e of t||[])"rejected"===e.status&&o(e.reason);return e().catch(o)})}(()=>import("./tab-benchmarks-tab-DfCuAClu.js"),__vite__mapDeps([0,1]))),In}async function Bn(){try{const e=document.getElementById("statusDot");document.getElementById("status").textContent="online",e.className="status-dot online",await gn();const t=await a("/api/dlq"),n=document.getElementById("dlqBadge");t.length?(n.textContent=t.length,n.classList.remove("hidden")):n.classList.add("hidden")}catch(e){document.getElementById("status").textContent="error",document.getElementById("statusDot").className="status-dot error"}}async function Sn(){await Bn()}function jn(e){document.querySelectorAll(".nav-item").forEach(e=>e.classList.remove("active"));const t=document.getElementById(e);t&&t.classList.add("active")}function An(){u(o.activeTab),document.querySelectorAll(".view, .view-sessions").forEach(e=>{e.classList.remove("active"),e.style.display&&(e.style.display="")});const e=document.querySelector(".msg-bar");e&&(e.style.display="")}async function Pn(e){const t=document.getElementById(e),n=encodeURIComponent((null==t?void 0:t.value)||window._crewHome||""),o=await a("/api/pick-folder?default="+n).catch(()=>null);(null==o?void 0:o.path)&&t&&(t.value=o.path)}function Ln(){const e=(location.hash||"#chat").slice(1),t=(e.split("?")[0]||"chat").split("/");return{view:t[0]||"chat",subtab:t[1],raw:e}}function Mn(){return Ln().view}function _n(e){const t=e&&String(e).trim()&&"undefined"!==e?e:"general",n=`#chat?project=${encodeURIComponent(t)}`;location.hash!==n&&history.replaceState(null,"",n)}async function Nn(){try{const e=await a("/api/ui/active-project");return String((null==e?void 0:e.projectId)||"").trim()||"general"}catch{return"general"}}async function Rn(e){const t=e&&String(e).trim()&&"undefined"!==e?String(e).trim():"general";try{await r("/api/ui/active-project",{projectId:t})}catch{}}async function On(){An(),document.getElementById("chatView").classList.add("active"),jn("navChat"),o.activeTab="chat",s();const e=document.querySelector(".msg-bar");e&&(e.style.display="none"),y();const t=document.getElementById("chatMessages");"true"===(null==t?void 0:t.dataset.historyLoading)&&await Yn();const n=t&&"true"===t.dataset.historyLoaded&&t.children.length>0;try{const e=(await a("/api/projects")).projects||[];o.projectsData={},e.forEach(e=>{o.projectsData[e.id]=e}),s(),Kt(e)}catch(c){console.warn("Failed to refresh projects dropdown:",c)}const i=new URLSearchParams(window.location.hash.replace(/^#chat\?/,"")).get("project");if(i)o.chatActiveProjectId=i;else{const e=await Nn();try{o.chatActiveProjectId=e||localStorage.getItem("crewswarm_chat_active_project_id")||"general"}catch{o.chatActiveProjectId=e||"general"}}window.location.hash.includes("?project=")||_n(o.chatActiveProjectId),console.log("🔵 [INIT] Active project from URL:",o.chatActiveProjectId);const r=document.getElementById("chatProjectTabs");r&&Array.from(r.children).forEach(e=>{e.dataset.projectId===o.chatActiveProjectId?e.classList.add("active"):e.classList.remove("active")});const l=document.getElementById("chatProjectSelect");l&&o.chatActiveProjectId&&l.querySelector('option[value="'+o.chatActiveProjectId+'"]')&&(l.value=o.chatActiveProjectId),Rn(o.chatActiveProjectId),gn(),zn(),async function(){try{const e=((await a("/api/agents-config")).agents||[]).find(e=>"crew-lead"===e.id);if(!e)return;window._crewLeadInfo={emoji:e.emoji||"🧠",name:e.name||"crew-lead",theme:e.theme||""};const t=document.getElementById("chatAgentTitle"),n=document.getElementById("chatAgentSub");t&&(t.textContent=(e.emoji||"🧠")+" "+(e.name||"Crew Lead")),n&&e.theme&&(n.textContent=e.theme+" — chat naturally, dispatch tasks to the crew")}catch(c){}}(),window.loadChatAgentSelector&&window.loadChatAgentSelector(),n?m("chat"):await Qn()}function Fn(){An(),document.getElementById("filesView").classList.add("active"),jn("navFiles"),o.activeTab="files",s(),po()}function Hn(){return"owner"}P({hideAllViews:An,setNavActive:jn}),R({hideAllViews:An,setNavActive:jn,refreshAgents:F}),ce({hideAllViews:An,setNavActive:jn}),He({hideAllViews:An,setNavActive:jn}),C(),E({hideAllViews:An,setNavActive:jn});let Dn=null;function zn(){if(Dn)return;const e=`http://${window.location.hostname||"127.0.0.1"}:5010/events`;console.log("[crewswarm] Starting EventSource listener for",e),Dn=new EventSource(e);const t="undefined"!=typeof localStorage&&"1"===localStorage.getItem("crewswarm_debug_sse");Dn.onmessage=e=>{if(e.data)try{const a=JSON.parse(e.data),s=e=>e&&"general"!==e?e:"general",r="owner";t&&console.log("[crewswarm] SSE:",a.type,e.data.slice(0,120));const l=document.getElementById("chatMessages");if(k(a))return;if("chat_stream"===a.type&&a.sessionId===r){const e=s(a.projectId);if(s(o.chatActiveProjectId)!==e)return;let t=document.getElementById("streaming-bubble");if(!t){const e=document.createElement("div");e.id="streaming-wrapper",e.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;";const n=document.createElement("div");n.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;";const o=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"};n.textContent=o.emoji+" "+o.name+" (streaming...)",t=document.createElement("div"),t.id="streaming-bubble",t.className="chat-bubble assistant",t.style.cssText="max-width:80%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid var(--border);",t._textNode=document.createTextNode(""),t.appendChild(t._textNode),e.appendChild(n),e.appendChild(t),l&&l.appendChild(e)}const n=(t.dataset.streamChunk||"")+a.token;return t.dataset.streamChunk=n,void(t._rafId||(t._rafId=requestAnimationFrame(()=>{const e=t.dataset.streamChunk||"";e&&(t._textNode||(t._textNode=document.createTextNode(""),t.appendChild(t._textNode)),t._textNode.textContent+=e,t.dataset.streamChunk=""),l&&(l.scrollTop=l.scrollHeight),t._rafId=null})))}if("draft_discarded"===a.type&&a.draftId){const e=document.querySelector('[data-draft-id="'+a.draftId+'"]');return void(e&&e.remove())}if("context_warning"===a.type&&"owner"===a.sessionId){const e=document.getElementById("contextWarningBanner");e&&e.remove();const t=document.createElement("div");t.id="contextWarningBanner";const n="critical"===a.level;t.style.cssText=`display:flex;align-items:center;gap:10px;padding:8px 14px;border-radius:8px;margin:6px 0;font-size:12px;background:${n?"rgba(239,68,68,0.1)":"rgba(245,158,11,0.1)"};border:1px solid ${n?"rgba(239,68,68,0.3)":"rgba(245,158,11,0.3)"};color:${n?"#f87171":"#f59e0b"};`,t.innerHTML=`<span style="flex:1;">${a.message}</span><button onclick="clearChatHistory()" style="padding:2px 8px;font-size:11px;border-radius:4px;border:1px solid currentColor;background:transparent;color:inherit;cursor:pointer;">Clear now</button><button onclick="this.parentElement.remove()" style="background:none;border:none;cursor:pointer;color:inherit;font-size:14px;padding:0 2px;">✕</button>`;const o=document.getElementById("chatMessages");return void(o&&(o.appendChild(t),o.scrollTop=o.scrollHeight))}if("chat_message"===a.type&&"owner"===a.sessionId){const e=s(o.chatActiveProjectId),t=s(a.projectId);if(e!==t)return void console.log("[crewswarm] ❌ SKIP - projectId mismatch:",{current:e||"(General)",message:t||"(General)"});if(console.log("[crewswarm] ✅ Displaying message for current session"),"user"===a.role){if(a.content===Jn)return console.log("[crewswarm] Skipping SSE echo of locally-sent message"),void(Jn=null);a.content!==Wn?(console.log("[crewswarm] Appending user bubble:",a.content.slice(0,50)),g("user",a.content),Wn=a.content):console.log("[crewswarm] Skipping duplicate user message")}else if("assistant"===a.role){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove());const e=String(a.content||"").trim();if(e&&function(e){if(!e)return"";for(let t=e.children.length-1;t>=0;t--){const n=e.children[t];if("streaming-wrapper"!==n.id&&!(n.children.length<2)&&String(n.style.alignItems||"").includes("flex-start"))return(n.children[1].textContent||"").trim()}return""}(l)===e)return Un=a.content,void(l&&(l.scrollTop=l.scrollHeight));const t=document.getElementById("streaming-wrapper"),n=document.getElementById("streaming-bubble");if(n){n._rafId&&cancelAnimationFrame(n._rafId),n._rafId=null;const e=n.dataset.streamChunk||"";e&&(n._textNode||(n._textNode=document.createTextNode(""),n.appendChild(n._textNode)),n._textNode.textContent+=e,n.dataset.streamChunk="")}if(t&&n){const e=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"},o=t.firstElementChild;o&&o!==n&&(o.textContent=e.emoji+" "+e.name);const s=a.content??"";n._textNode?n._textNode.textContent=s:n.textContent=s,t.removeAttribute("id"),n.removeAttribute("id"),delete n.dataset.streamChunk,Un=a.content}else{t&&t.remove();const e=a.content===Un&&function(e,t){if(!e||null==t)return!1;const n=String(t).trim();if(!n)return!1;for(let o=e.children.length-1;o>=0;o--){const t=e.children[o];if("streaming-wrapper"!==t.id&&(!(t.children.length<2)&&String(t.style.alignItems||"").includes("flex-start")&&(t.children[1].textContent||"").trim()===n))return!0}return!1}(l,a.content);e?console.log("[crewswarm] Skipping duplicate assistant message"):(console.log("[crewswarm] Appending assistant bubble (final)"),g("assistant",a.content,a.fallbackModel,a.fallbackReason,a.model,a.engineUsed),Un=a.content)}}return void(l&&(l.scrollTop=l.scrollHeight))}if("pending_project"===a.type&&"owner"===a.sessionId&&a.pendingProject&&l)return Kn(l,a.pendingProject),void(l.scrollTop=l.scrollHeight);if("agent_working"===a.type&&a.agent){const e=document.getElementById("coding-dot-"+a.agent);e&&(e.style.display="inline-flex")}if("agent_idle"===a.type&&a.agent){const e=document.getElementById("coding-dot-"+a.agent);e&&(e.style.display="none")}if("opencode_event"===a.type){const e=document.getElementById("ocFeed"),t=document.getElementById("ocFeedDot");if(!e)return;t&&(t.style.display="inline-block");const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:8px;padding:5px 10px;border-radius:8px;background:var(--bg-2);font-size:12px;font-family:var(--font-mono,monospace);animation:fadeIn .25s ease;";const s=new Date(a.ts||Date.now()).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});let i="⚙️",r="";if("session_start"===a.kind){i="▶",o.style.borderLeft="3px solid var(--green-hi)";var n=a.dir||"";r="session started"+(n?" — "+n.split("/").pop():"")}else if("session_end"===a.kind)i="■",o.style.borderLeft="3px solid var(--text-3)",r="session ended",t&&(t.style.display="none");else if("file_edit"===a.kind)i="✏️",o.style.borderLeft="3px solid var(--amber)",r=(a.file||a.path||"")+(a.extra?' <span style="opacity:.5;">'+a.extra+"</span>":"");else if("error"===a.kind)i="✗",o.style.borderLeft="3px solid var(--red-hi)",o.style.color="var(--red-hi)",r=a.message||"error";else if("tool"===a.kind){const e={read_file:"var(--accent)",write_file:"var(--amber)",bash:"var(--purple)",list_directory:"var(--green)",grep:"var(--green)"}[a.tool]||"var(--text-2)";i="done"===a.phase?"✓":"→",o.style.borderLeft="3px solid "+e,o.style.color="done"===a.phase?"var(--text-2)":"var(--text-1)",r='<span style="color:'+e+';font-weight:600;">'+(a.tool||"")+"</span>"+(a.label?' <span style="opacity:.6;">'+a.label+"</span>":"")}for(o.innerHTML='<span style="opacity:.4;flex-shrink:0;">'+s+'</span><span style="flex-shrink:0;">'+i+'</span><span style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">'+r+"</span>",e.appendChild(o);e.children.length>80;)e.removeChild(e.firstChild);return void(e.scrollTop=e.scrollHeight)}if("agent_working"===a.type&&a.agent){const e="agent-spinner-"+(a.taskId||a.agent);if(l&&!document.getElementById(e)){const t=document.createElement("div");t.id=e,t.className="msg a",t.style.cssText="opacity:.7; font-style:italic;",t.innerHTML='<div class="meta"><strong>'+a.agent+'</strong> · working…</div><div class="t" style="display:flex;align-items:center;gap:8px;"><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent);animation:pulse 1s ease-in-out infinite;"></span>Processing task…</div>',l.appendChild(t),l.scrollTop=l.scrollHeight}return}if("agent_reply"===a.type||a.from&&a.content){if(!a.from||!a.content)return;if(a._passthroughSummary)return;const e="agent-spinner-"+(a.taskId||a.from),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+a.from);return n&&n.remove(),g("🤖 "+a.from,a.content,!1,null,null,a.engineUsed),l&&(l.scrollTop=l.scrollHeight),void i(a.from+" finished a task")}if("task.timeout"===a.type&&a.agent){const e="agent-spinner-"+(a.taskId||a.agent),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+a.agent);n&&n.remove();const o="[crew-lead] Task to "+a.agent+" timed out (no reply in 90s). Consider @@SERVICE restart "+a.agent+" or re-dispatch to another agent.";if(l){const e=document.createElement("div");e.className="msg a",e.style.cssText="opacity:.85; font-style:italic; color:var(--text-3);",e.innerHTML='<div class="meta"><strong>'+a.agent+'</strong> · no reply</div><div class="t">'+h(o)+"</div>",l.appendChild(e),l.scrollTop=l.scrollHeight}return void i("Task to "+a.agent+" timed out")}if("pipeline_progress"===a.type){let e;e=a.agents?"Wave "+(a.waveIndex+1)+"/"+a.totalWaves+" → "+a.agents.join(" + "):"Step "+(a.stepIndex+1)+"/"+a.total+" → "+a.agent;const t=document.createElement("div");return t.style.cssText="font-size:11px;color:var(--text-3);padding:2px 8px;margin:2px 0;",t.textContent="↳ "+e,void(l&&(l.appendChild(t),l.scrollTop=l.scrollHeight))}if("pipeline_quality_gate"===a.type){const e=document.createElement("div"),t=a.willRetry?" — retrying wave":" — advancing anyway";return e.style.cssText="font-size:11px;color:var(--warning, #e8a030);padding:2px 8px;margin:2px 0;",e.textContent="⚠️ Wave "+(a.waveIndex+1)+" quality gate: "+(a.issues||[]).join("; ")+t,void(l&&(l.appendChild(e),l.scrollTop=l.scrollHeight))}if("project_launched"===a.type&&a.project){const e=a.project.projectId||a.project.id;return void setTimeout(async()=>{await Xt(),e&&pn(e);const t=document.getElementById("chatMessages");if(t){const n=document.createElement("div");n.style.cssText="font-size:11px;color:var(--green);padding:2px 8px;margin:2px 0;",n.textContent='📁 Project "'+(a.project.name||e)+'" registered — selected in chat',t.appendChild(n),t.scrollTop=t.scrollHeight}},800)}if("pipeline_done"===a.type){const e=document.createElement("div");return e.style.cssText="font-size:11px;color:var(--green);padding:2px 8px;margin:2px 0;",e.textContent="✅ Pipeline complete",void(l&&(l.appendChild(e),l.scrollTop=l.scrollHeight))}if("confirm_run_cmd"===a.type&&a.approvalId)return void function(e,t,n){if(document.getElementById("cmd-approval-"+e))return;const o=document.createElement("div");o.id="cmd-approval-"+e,o.style.cssText=["position:fixed;bottom:80px;right:24px;z-index:9999;","background:var(--bg-card);border:1px solid var(--border);border-radius:12px;","padding:16px 20px;max-width:440px;box-shadow:0 8px 32px rgba(0,0,0,.4);","display:flex;flex-direction:column;gap:10px;"].join("");const a=document.createElement("div");a.style.cssText="font-size:13px;font-weight:600;color:var(--text-1);",a.textContent="🔐 "+t+" wants to run a command";const s=document.createElement("code");s.style.cssText="display:block;font-size:12px;color:var(--accent);background:var(--bg-1);padding:6px 10px;border-radius:6px;word-break:break-all;",s.textContent=n;const r=document.createElement("label");r.style.cssText="display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-2);cursor:pointer;";const l=document.createElement("input");l.type="checkbox",l.style.cssText="width:14px;height:14px;cursor:pointer;accent-color:var(--green);";const c=n.trim().split(/\s+/)[0]+" *";r.appendChild(l),r.appendChild(document.createTextNode("Always allow "));const d=document.createElement("code");d.style.cssText="font-size:11px;background:var(--bg-1);padding:2px 6px;border-radius:4px;color:var(--accent);",d.textContent=c,r.appendChild(d);const p=document.createElement("div");p.style.cssText="font-size:11px;color:var(--text-3);";let m=60;p.textContent="Auto-reject in "+m+"s";const u=setInterval(()=>{m--,p.textContent="Auto-reject in "+m+"s",m<=0&&(clearInterval(u),o.remove())},1e3),g=document.createElement("div");g.style.cssText="display:flex;gap:8px;";const h=document.createElement("button");h.textContent="✅ Allow",h.style.cssText="flex:1;padding:8px;border-radius:8px;border:none;background:var(--green);color:#fff;cursor:pointer;font-weight:600;font-size:13px;",h.onclick=async()=>{clearInterval(u),o.remove(),l.checked&&(await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:c})}),i("Allowlisted: "+c)),await fetch("/api/cmd-approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}).catch(e=>i("Approve failed: "+e.message,!0)),l.checked||i(t+": command approved")};const v=document.createElement("button");v.textContent="⛔ Deny",v.style.cssText="flex:1;padding:8px;border-radius:8px;border:none;background:var(--red-hi);color:#fff;cursor:pointer;font-weight:600;font-size:13px;",v.onclick=async()=>{clearInterval(u),o.remove(),await fetch("/api/cmd-reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}).catch(e=>i("Reject failed: "+e.message,!0)),i(t+": command denied")},g.appendChild(h),g.appendChild(v),o.appendChild(a),o.appendChild(s),o.appendChild(r),o.appendChild(p),o.appendChild(g),document.body.appendChild(o)}(a.approvalId,a.agent,a.cmd);if("telemetry"===a.type&&a.payload){window._telemetryEvents=window._telemetryEvents||[],window._telemetryEvents.push(a.payload),window._telemetryEvents.length>100&&window._telemetryEvents.shift();const e=document.getElementById("toolMatrixView");e&&e.classList.contains("active")&&fn(window._telemetryEvents)}}catch{}else console.warn("[crewswarm] SSE message with null/empty data")},Dn.onopen=()=>{console.log("[crewswarm] SSE connection opened"),window._sseReconnectDelay=2e3},Dn.onerror=e=>{console.error("[crewswarm] SSE error:",e),Dn.close(),Dn=null,window._sseReconnectTimer&&clearTimeout(window._sseReconnectTimer),window._sseReconnectTimer=setTimeout(()=>{window._sseReconnectTimer=null,window._sseReconnectDelay=Math.min(2*(window._sseReconnectDelay||2e3),3e4),zn()},window._sseReconnectDelay||2e3)}}const Gn=[{label:"npm",pattern:"npm *",desc:"install, run, build, test…"},{label:"node",pattern:"node *",desc:"run any node script"},{label:"python",pattern:"python *",desc:"python / python3 scripts"},{label:"pip",pattern:"pip *",desc:"pip install packages"},{label:"git",pattern:"git *",desc:"all git operations"},{label:"cursor",pattern:"cursor *",desc:"open files in Cursor"},{label:"make",pattern:"make *",desc:"Makefile targets"},{label:"yarn",pattern:"yarn *",desc:"yarn install / build / run"},{label:"pnpm",pattern:"pnpm *",desc:"pnpm package manager"},{label:"ls / cat / echo",pattern:"ls *",desc:"read-only shell utilities"}];async function $n(){const e=document.getElementById("cmdAllowlistItems"),t=document.getElementById("cmdPresets");if(!e)return;const n=(await a("/api/cmd-allowlist").catch(()=>({list:[]}))).list||[];t&&(t.innerHTML="",Gn.forEach(function(e){const o=n.includes(e.pattern),a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 6px;border-radius:6px;transition:background 0.1s;",a.onmouseover=function(){a.style.background="var(--bg-hover)"},a.onmouseout=function(){a.style.background=""};const s=document.createElement("input");s.type="checkbox",s.checked=o,s.style.cssText="width:14px;height:14px;cursor:pointer;accent-color:var(--green);flex-shrink:0;",s.onchange=async function(){s.checked?await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:e.pattern})}).catch(e=>i("Failed to add pattern: "+e.message,!0)):await fetch("/api/cmd-allowlist",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:e.pattern})}).catch(e=>i("Failed to remove pattern: "+e.message,!0)),$n()};const r=document.createElement("code");r.style.cssText="font-size:12px;color:var(--accent);min-width:90px;",r.textContent=e.pattern;const l=document.createElement("span");l.style.cssText="font-size:11px;color:var(--text-3);",l.textContent=e.desc,a.appendChild(s),a.appendChild(r),a.appendChild(l),t.appendChild(a)}));const o=new Set(Gn.map(function(e){return e.pattern})),s=t?n.filter(function(e){return!o.has(e)}):n;if(e.innerHTML="",s.length)for(const a of s){const t=document.createElement("div");t.style.cssText="display:flex;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid var(--border);";const n=document.createElement("code");n.style.cssText="flex:1;font-size:12px;color:var(--accent);",n.textContent=a;const o=document.createElement("button");o.textContent="✕",o.style.cssText="border:none;background:transparent;color:var(--text-3);cursor:pointer;font-size:14px;padding:0 4px;",o.title="Remove",o.onclick=async function(){await fetch("/api/cmd-allowlist",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:a})}).catch(e=>i("Failed to delete pattern: "+e.message,!0)),$n()},t.appendChild(n),t.appendChild(o),e.appendChild(t)}else e.innerHTML='<div style="color:var(--text-3);font-size:12px;padding:4px 0;">'+(t?"No custom patterns yet.":"No patterns yet.")+"</div>"}async function Vn(){const e=document.getElementById("cmdAllowlistInput"),t=e?e.value.trim():"";t&&(await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:t})}).catch(e=>i("Failed to add pattern: "+e.message,!0)),e.value="",$n())}window._telemetryEvents=window._telemetryEvents||[];const qn=()=>vn(kn);function Kn(e,{draftId:t,name:n,outputDir:o,roadmapMd:a}){function s(e){return(e.match(/^- \[ \]/gm)||[]).length}const i=document.createElement("div");i.setAttribute("data-draft-id",t),i.style.cssText="width:100%;display:flex;flex-direction:column;gap:4px;";const l=document.createElement("div");l.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;",l.textContent="🗺️ Roadmap draft — review before building";const c=document.createElement("div");c.style.cssText="width:100%;border:1px solid var(--border);border-radius:12px;overflow:hidden;background:var(--bg-card);";const d=document.createElement("div");d.style.cssText="background:var(--bg-card2);padding:10px 14px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border);",d.innerHTML='<div><div style="font-size:13px;font-weight:600;color:var(--accent);">🚀 '+n+'</div><div style="font-size:11px;color:var(--blue);margin-top:2px;">'+o+'</div></div><span style="font-size:10px;color:var(--text-3);padding:2px 7px;background:var(--bg-card2);border-radius:10px;" class="task-count">'+s(a)+" tasks</span>";const p=document.createElement("textarea");p.value=a,p.spellcheck=!1,p.style.cssText="width:100%;background:var(--bg-card);border:none;outline:none;color:var(--text-1);font-size:11.5px;font-family:SF Mono,Monaco,Menlo,monospace;line-height:1.6;padding:12px 14px;resize:none;min-height:160px;max-height:320px;display:block;",setTimeout(()=>{p.style.height="",p.style.height=Math.min(p.scrollHeight,320)+"px"},50),p.addEventListener("input",()=>{p.style.height="",p.style.height=Math.min(p.scrollHeight,320)+"px",d.querySelector(".task-count").textContent=s(p.value)+" tasks"});const m=document.createElement("div");m.style.cssText="display:flex;gap:8px;align-items:center;padding:10px 14px 12px;border-top:1px solid var(--border);background:var(--bg-card2);";const u=document.createElement("button");u.textContent="▶ Start Building",u.style.cssText="background:var(--green-hi);color:#000;border:none;border-radius:8px;padding:8px 16px;font-size:12px;font-weight:700;cursor:pointer;",u.onclick=async()=>{u.disabled=!0,u.textContent="⏳ Launching…";try{const e=await r("/api/crew-lead/confirm-project",{draftId:t,roadmapMd:p.value});e.ok?(c.innerHTML='<div style="padding:14px;color:var(--green-hi);font-size:13px;font-weight:600;">✅ '+n+' — project created, PM loop running!<br><span style="color:var(--blue);font-size:11px;font-weight:400">'+(e.outputDir||o)+"</span></div>",g("assistant","🚀 "+n+" is building. Check the Projects tab to watch progress.")):(u.disabled=!1,u.textContent="▶ Start Building",v.textContent="⚠️ "+(e.error||"Launch failed"))}catch(e){u.disabled=!1,u.textContent="▶ Start Building",v.textContent="⚠️ "+e.message}};const h=document.createElement("button");h.textContent="Discard",h.style.cssText="background:none;border:1px solid var(--border);color:var(--text-3);border-radius:8px;padding:8px 14px;font-size:12px;cursor:pointer;",h.onclick=async()=>{await r("/api/crew-lead/discard-project",{draftId:t}).catch(()=>{}),i.remove()};const v=document.createElement("span");v.style.cssText="font-size:11px;color:var(--blue);margin-left:auto;",v.textContent="Edit above, then confirm",m.appendChild(u),m.appendChild(h),m.appendChild(v),c.appendChild(d),c.appendChild(p),c.appendChild(m),i.appendChild(l),i.appendChild(c),e.appendChild(i),e.scrollTop=e.scrollHeight}let Un="",Wn="",Jn=null;const{loadChatHistory:Qn,waitForChatHistoryIdle:Yn,chatAtAtInput:Xn,chatKeydown:Zn,sendChat:eo,clearChatHistory:to,stopAll:no,killAll:oo,killPassthrough:ao,refreshSessionIndicator:so,clearPassthroughSession:io,resetSendButton:ro,handleImageUpload:lo,toggleVoiceRecording:co}=w({postJSON:r,getJSON:a,appendChatBubble:g,showNotification:i,state:o,getChatSessionId:()=>"owner",getChatActiveProjectId:()=>o.chatActiveProjectId,getCrewLeadInfo:()=>window._crewLeadInfo,appendRoadmapCard:Kn,getLastAppendedAssistantContent:()=>Un,setLastAppendedAssistantContent:e=>{Un=e},setLastAppendedUserContent:e=>{Wn=e},setLastSentContent:e=>{Jn=e}});async function po(e){const t=document.getElementById("filesContent"),n=document.getElementById("filesDir").value.trim()||window._crewCwd||(window._crewHome?window._crewHome+"/CrewSwarm":"");d(t,"Scanning "+n+"...");try{const e=await a("/api/files?dir="+encodeURIComponent(n));if(!e.files||!e.files.length)return void c(t,"No files found in "+n);const o={};e.files.forEach(e=>{const t=e.path.split(".").pop().toLowerCase()||"other";o[t]||(o[t]=[]),o[t].push(e)});const s=["html","css","js","mjs","ts","json","md","sh","txt","other"],i={html:"🌐",css:"🎨",js:"⚡",mjs:"⚡",ts:"🔷",json:"📋",md:"📝",sh:"🖥️",txt:"📄",other:"📁"};let r='<div style="display:grid;gap:1rem;padding:4px 0;">';for(const t of s)o[t]&&(r+="<div>",r+='<div style="font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:0.08em;margin-bottom:8px;padding-left:2px;">'+(i[t]||"📁")+" ."+t+" — "+o[t].length+" file"+(o[t].length>1?"s":"")+"</div>",r+='<div style="display:grid;gap:6px;">',o[t].sort((e,t)=>t.mtime-e.mtime).forEach(e=>{const t=e.path.replace(n+"/",""),o=go(e.mtime),a=ho(e.size);r+='<div class="file-row">',r+='<div class="file-info"><span class="file-name">'+t+'</span><span class="file-meta">'+a+" · "+o+"</span></div>",r+='<div class="file-actions">',r+='<a href="cursor://file/'+e.path+'" class="file-btn file-btn-cursor" title="Open in Cursor">Cursor</a>',r+='<a href="opencode://open?path='+encodeURIComponent(e.path)+'" class="file-btn file-btn-opencode" title="Open in OpenCode">OpenCode</a>',r+='<button data-action="previewFile" data-arg=\''+e.path.replace(/'/g,"&#39;")+'\' data-self="1" class="file-btn" title="Preview">👁</button>',r+="</div></div>"}),r+="</div></div>");r+="</div>",r+='<div id="file-preview-pane" style="display:none;margin-top:1rem;background:#0d1117;border:1px solid var(--border);border-radius:8px;overflow:hidden;"><div id="file-preview-bar" style="display:flex;align-items:center;gap:8px;padding:8px 12px;background:#0d1420;border-bottom:1px solid var(--border);font-size:12px;color:var(--text-2);"><span id="file-preview-name"></span><button data-action="closePreviewPane" style="margin-left:auto;background:none;border:none;color:var(--text-2);cursor:pointer;">✕</button></div><pre id="file-preview-content" style="margin:0;padding:1rem;font-size:0.75rem;overflow:auto;max-height:400px;"></pre></div>',t.innerHTML=r}catch(o){l(t,"Error: "+o.message)}}async function mo(e,t){const n=document.getElementById("file-preview-pane"),o=document.getElementById("file-preview-content"),s=document.getElementById("file-preview-name");if(n){s.textContent=e.split("/").pop(),o.textContent="Loading...",n.style.display="block",n.scrollIntoView({behavior:"smooth",block:"nearest"});try{const t=await a("/api/file-content?path="+encodeURIComponent(e));o.textContent=t.content||"(empty)"}catch(i){o.textContent="Error: "+i.message}}}function uo(){const e=document.getElementById("file-preview-pane");e&&(e.style.display="none")}function go(e){const t=Date.now()-e,n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return n+"m ago";const o=Math.floor(n/60);return o<24?o+"h ago":Math.floor(o/24)+"d ago"}function ho(e){return e<1024?e+"B":e<1048576?(e/1024).toFixed(1)+"KB":(e/1024/1024).toFixed(1)+"MB"}function vo(){An(),document.getElementById("settingsView").classList.add("active"),jn("navSettings"),o.activeTab="settings",s();const e=(location.hash||"").replace("#settings/",""),t={system:"engines",telegram:"comms",whatsapp:"comms"}[e]||e;fo(["usage","engines","comms","security","webhooks"].includes(t)?t:"usage")}function fo(e){var t;["usage","engines","comms","security","webhooks"].forEach(t=>{const n=document.getElementById("stab-panel-"+t),o=document.getElementById("stab-"+t);n&&o&&(n.style.display=t===e?"usage"===t?"grid":"block":"none",o.classList.toggle("active",t===e))}),"usage"===e&&(hn(),xn()),"engines"===e&&(vt(),ft(),yt(),wt(),bt(),xt(),kt(),Ct(),Et(),It(),Tt(),Bt(),St(),jt()),"comms"===e&&Vt(),"security"===e&&($n(),At()),(null==(t=document.getElementById("settingsView"))?void 0:t.classList.contains("active"))&&history.replaceState(null,"","#settings/"+e)}function yo(){An(),document.getElementById("enginesView").classList.add("active"),jn("navEngines"),Ae()}null==(e=document.getElementById("attachImageBtn"))||e.addEventListener("click",()=>{document.getElementById("imageUpload").click()}),null==(t=document.getElementById("imageUpload"))||t.addEventListener("change",lo),null==(n=document.getElementById("recordVoiceBtn"))||n.addEventListener("click",co),window.loadChatHistory=Qn,window.getChatSessionId=Hn,window.selectProjectTab=e=>{const t=e&&String(e).trim()&&"undefined"!==e?e:"general",n=o.chatActiveProjectId;console.log("🔵 [TAB CLICK] START",t,"- from:",n);const a=document.getElementById("chatProjectTabs");if(!a)return void console.error("🔵 [TAB CLICK] ERROR: chatProjectTabs container not found!");if(n===t)return void console.log("🔵 [TAB CLICK] Already on this tab, skipping reload");_n(t),Array.from(a.children).forEach(e=>{e.classList.remove("active")});const s=Array.from(a.children).find(e=>e.dataset.projectId===t);s&&s.classList.add("active"),o.chatActiveProjectId=t;try{localStorage.setItem("crewswarm_chat_active_project_id",t)}catch{}Rn(t),console.log("🔵 [TAB CLICK] Updated state:",{projectId:o.chatActiveProjectId,sessionId:"owner",url:window.location.hash}),console.log("🔵 [TAB CLICK] Calling loadChatHistory()..."),Qn().then(()=>{console.log("🔵 [TAB CLICK] loadChatHistory() completed");const e=document.getElementById("chatMessages");console.log("🔵 [TAB CLICK] Messages in DOM:",(null==e?void 0:e.children.length)||0)}).catch(e=>{console.error("🔵 [TAB CLICK] loadChatHistory() ERROR:",e)})},window.addEventListener("focus",()=>{(async function(){if("chat"!==Ln().view)return;const e=await Nn(),t=e&&"undefined"!==e?e:"general";t!==(o.chatActiveProjectId&&"undefined"!==o.chatActiveProjectId?o.chatActiveProjectId:"general")&&window.selectProjectTab&&window.selectProjectTab(t)})().catch(()=>{})}),Lt({showSettings:vo,showSettingsTab:fo}),Pt({getModels:F,populateModelDropdown:le}),Ye({hideAllViews:An,setNavActive:jn,loadAgents:F}),De(),b({hideAllViews:An,setNavActive:jn});const wo=async()=>{const{showBenchmarks:e}=await Tn();e({hideAllViews:An,setNavActive:jn})};function bo(){An(),document.getElementById("memoryView").classList.add("active"),jn("navMemory"),A()}function xo(){An(),document.getElementById("cliProcessView").classList.add("active"),jn("navCLI"),window.initCLIProcess&&window.initCLIProcess()}function ko(){An(),document.getElementById("toolMatrixView").classList.add("active"),jn("navToolMatrix"),mn()}async function Co(){const e=document.getElementById("webhookChannel").value.trim()||"test";let t={};try{const e=document.getElementById("webhookPayload").value.trim();e&&(t=JSON.parse(e))}catch{t={raw:document.getElementById("webhookPayload").value}}const n=document.getElementById("webhookTestResult");try{const o=await fetch("/proxy-webhook/"+e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await o.json();n.textContent=a.ok?"✅ Sent to RT bus":"❌ "+(a.error||"failed"),n.style.color=a.ok?"var(--green)":"var(--red)"}catch(o){n.textContent="❌ "+o.message,n.style.color="var(--red)"}}async function Eo(){document.getElementById("pendingApprovals").innerHTML='<div style="color:var(--text-3);font-size:12px;">Pending skill approvals appear here when an agent triggers a skill marked requiresApproval. You will also receive a Telegram notification with inline Approve/Reject buttons if Telegram is configured.</div>'}function Io(){on({hideAllViews:An,setNavActive:jn})}function To(){nn({hideAllViews:An,setNavActive:jn})}qt({showChat:On,showBuild:Io}),Bn(),setInterval(Bn,3e4),(async()=>{try{const e=(await a("/api/projects")).projects||[];o.projectsData={},e.forEach(e=>{o.projectsData[e.id]=e}),Kt(e),s(),"#projects"===location.hash&&To()}catch{}})(),document.getElementById("refreshBtn").onclick=Sn,document.getElementById("runBuildBtn").onclick=Ut,document.getElementById("continuousBuildBtn").onclick=Wt,document.getElementById("stopBuildBtn").onclick=Jt,document.getElementById("stopContinuousBtn").onclick=Qt,document.getElementById("enhancePromptBtn").onclick=Yt,Cn(),document.getElementById("newProjectBtn").onclick=()=>{const e=document.getElementById("newProjectForm");e.style.display="none"===e.style.display?"block":"none"},document.getElementById("npCancelBtn").onclick=()=>{document.getElementById("newProjectForm").style.display="none"},document.getElementById("npCreateBtn").onclick=async()=>{const e=document.getElementById("npName").value.trim(),t=document.getElementById("npDesc").value.trim(),n=document.getElementById("npOutputDir").value.trim(),o=document.getElementById("npFeaturesDoc").value.trim();if(e&&n)try{const a=await r("/api/projects",{name:e,description:t,outputDir:n,featuresDoc:o});i(`Project "${a.project.name}" created!`),document.getElementById("newProjectForm").style.display="none",document.getElementById("npName").value="",document.getElementById("npDesc").value="",document.getElementById("npOutputDir").value="",document.getElementById("npFeaturesDoc").value="",Xt()}catch(a){i("Failed: "+a.message,!0)}else i("Name and output directory required",!0)};const Bo={chat:On,"swarm-chat":x,swarm:_e,rt:Me,dlq:Le,files:Fn,services:L,agents:O,models:ze,settings:vo,engines:yo,skills:me,"run-skills":pe,benchmarks:wo,"tool-matrix":ko,build:Io,messaging:Mt,projects:To,contacts:Ee,memory:bo,workflows:I,"cli-process":xo,prompts:de};for(const[Lo,Mo]of Object.entries(Bo)){const e=Mo,t=function(...t){const n=location.hash||"";return"chat"===Lo?n.startsWith("#chat")||history.replaceState(null,"","#chat"):history.replaceState(null,"","#"+Lo),e(...t)};Bo[Lo]=t,window[e.name]=t}function So(e){const t=String(e||"chat").split("?")[0].split("/")[0];(Bo[t]||Bo.chat)()}(async()=>{if(await v())return;const{view:e,subtab:t}=Ln();"1"===new URLSearchParams(window.location.search).get("focus")?setTimeout(()=>{const e=document.getElementById("chatInput");e&&(So("chat"),e.focus())},500):(So(e||"chat"),"settings"===e&&t&&fo(t))})(),window.addEventListener("hashchange",()=>{const{view:e,subtab:t}=Ln(),n=Po[e];n?(n(),"settings"===e&&t&&fo(t)):On()}),fetch("/api/env").then(e=>e.json()).then(e=>{window._crewHome=e.HOME||"",window._crewCwd=e.cwd||"";const t=document.getElementById("filesDir");t&&!t.value&&(t.value=e.cwd||"")}).catch(()=>{}),F().catch(e=>console.error("Initial agents-config load failed:",e)),Sn(),function(){function e(e){if(e.closest("form"))return;const t=document.createElement("form");t.autocomplete="off",t.onsubmit=()=>!1,t.style.cssText="margin:0;padding:0;display:contents;";const n=document.createElement("input");n.type="text",n.autocomplete="username",n.setAttribute("aria-hidden","true"),n.style.cssText="display:none;position:absolute;width:0;height:0;opacity:0;",t.appendChild(n),e.parentNode.insertBefore(t,e),t.appendChild(e)}function t(t){(t||document).querySelectorAll('input[type="password"]').forEach(e)}t();new MutationObserver(n=>{for(const o of n)for(const n of o.addedNodes)1===n.nodeType&&(n.matches&&n.matches('input[type="password"]')?e(n):t(n))}).observe(document.body,{childList:!0,subtree:!0})}();const jo={showChat:On,showSwarm:_e,showRT:Me,showBuild:Io,showFiles:Fn,showDLQ:Le,showProjects:To,showAgents:O,showModels:ze,showEngines:yo,showSkills:me,showRunSkills:pe,showBenchmarks:wo,showToolMatrix:ko,showServices:L,showSettings:vo,pickFolder:e=>Pn(e),loadFiles:e=>po(),clearChatHistory:to,clearAgentChat:()=>{const e=document.getElementById("agentChatSelector"),t=document.getElementById("agentChatMessages"),n=document.getElementById("agentChatInput");t&&(t.innerHTML='<div class="empty-state">No messages yet. Start chatting!</div>'),n&&(n.value=""),(null==e?void 0:e.value)&&i("Chat history cleared","success")},sendChat:eo,stopAll:no,killAll:oo,stopPassthrough:ao,clearPassthroughSession:io,loadServices:M,saveRTToken:gt,lockConfig:ut,unlockConfig:mt,startCrew:H,toggleEmojiPicker:e=>oe(e),bulkSetRoute:(e,t)=>ae(e,t),loadSpending:bn,resetSpending:wn,saveGlobalCaps:yn,loadOcStats:qn,addAllowlistPattern:Vn,sendTestWebhook:Co,startTgBridge:Gt,stopTgBridge:zt,saveTgConfig:Dt,loadTelegramSessions:Ht,loadTgMessages:Ft,startWaBridge:Ot,stopWaBridge:Rt,saveWaConfig:Nt,loadWaMessages:_t,saveOpencodeSettings:pt,saveOpencodeModel:dt,saveGlobalFallback:ct,toggleBgConsciousness:lt,toggleCursorWaves:rt,toggleAutonomousMentions:it,toggleClaudeCode:st,toggleCodexExecutor:at,toggleGeminiCliExecutor:ot,toggleCrewCliExecutor:nt,toggleOpencodeExecutor:tt,saveGlobalOcLoop:et,saveGlobalOcLoopRounds:Ze,savePassthroughNotify:Xe,toggleAddSkill:ye,toggleImportSkill:fe,importSkillFromUrl:ve,showSkills:me,saveSkill:he,cancelSkillForm:ge,loadRunSkills:ue,loadBenchmarks:async()=>(await Tn()).loadBenchmarks(),loadBenchmarkLeaderboard:async()=>(await Tn()).loadBenchmarkLeaderboard(),loadBenchmarkTasks:async()=>(await Tn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Tn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Tn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Tn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadEngines:Ae,toggleImportEngine:je,importEngineFromUrl:Se,deleteEngine:e=>Pe(e),loadToolMatrix:mn,loadBuildProjectPicker:Zt,scrollRTToBottom:()=>{const e=document.getElementById("rtView");e&&(e.scrollTop=e.scrollHeight)},toggleRTPause:Re,clearRTMessages:Ne,togglePmAdvanced:()=>{const e=document.getElementById("pmAdvanced");e&&(e.style.display="none"===e.style.display?"block":"none")},toggleRTTokenVis:()=>{const e=document.getElementById("rtTokenInput");e&&(e.type="password"===e.type?"text":"password")},restartService:e=>N(e),stopService:e=>_(e),closePreviewPane:uo,previewFile:(e,t)=>mo(e),replayDLQ:e=>Fe(e),deleteDLQ:e=>Oe(e),runSkillFromUI:e=>be(e),editSkill:e=>xe(e),deleteSkill:e=>ke(e),restartAgentFromUI:e=>un(e),saveSearchTool:e=>Ke(e),testSearchTool:e=>$e(e),saveBuiltinKey:e=>We(e),testBuiltinProvider:e=>qe(e),fetchBuiltinModels:(e,t)=>Qe(e,t),saveKey:e=>Ue(e),testKey:e=>Ve(e),fetchModels:(e,t)=>Je(e,t),toggleKeyVis:(e,t)=>Ge(e,t),toggleAgentBody:e=>D(e),deleteAgent:e=>te(e),saveAgentModel:e=>Q(e),saveAgentFallback:e=>Z(e),saveAgentVoice:e=>X(e),toggleEmojiPicker:e=>oe(e),saveAgentIdentity:e=>Y(e),saveAgentPrompt:e=>J(e),resetAgentSession:e=>ee(e),saveAgentTools:e=>W(e),applyToolPreset:e=>ne(e),setRoute:(e,t)=>z(e,t),saveOpenCodeConfig:e=>V(e),saveOpenCodeFallback:e=>$(e),saveCursorCliConfig:e=>U(e),saveClaudeCodeConfig:e=>K(e),saveCodexConfig:e=>G(e),saveGeminiCliConfig:e=>q(e),saveCrewCLIConfig:e=>re(e),"pm-toggle":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&n.running?cn(e):dn(e)},"edit-roadmap":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&ln(e,n.roadmapFile)},"retry-failed":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&rn(n.roadmapFile)},"save-roadmap":e=>sn(e),"reset-failed":e=>an(e),showSettingsTab:e=>fo(e)};let Ao=!1;document.addEventListener("touchstart",e=>{if(!(e.target instanceof Element))return;e.target.closest("[data-action]")&&(Ao=!0,setTimeout(()=>{Ao=!1},500))},{passive:!0}),document.addEventListener("click",e=>{if(!(e.target instanceof Element))return;const t=e.target.closest("[data-action]");if(!t)return;if(Ao)return void e.preventDefault();e.stopPropagation();const n=t.dataset.action,o=jo[n];if(!o)return void console.warn("[crewswarm] unknown data-action:",n);const a=t.dataset.arg??null,s=t.dataset.arg2??null,i="1"===t.dataset.self;null!==a&&null!==s?o(a,s):null!==a&&i?o(a,t):null!==a?o(a):i?o(t):o()}),document.addEventListener("change",e=>{const t=e.target.closest("[data-onchange]");if(!t)return;const n=jo[t.dataset.onchange];if(!n)return;const o="this.value"===t.dataset.onchangeArg?t.value:null;null!==o?n(o):n()}),document.addEventListener("DOMContentLoaded",()=>{f("activeTasksPanel"),Ie();const e=document.getElementById("dashSelfLink");e&&(e.href=window.location.origin,e.textContent=window.location.host),document.querySelectorAll(".nav-item").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const n=e.dataset.view;if(!n)return;if(Mn()!==n)return void(window.location.hash=n);const o=Po[n];o&&o()})});const t=document.getElementById("chatInput");t&&!t.dataset.boundChatComposer&&(t.dataset.boundChatComposer="1",t.addEventListener("keydown",Zn),t.addEventListener("input",Xn));const n=document.getElementById("chatSendBtn")||document.querySelector('[data-action="sendChat"]');n&&!n.dataset.boundChatComposer&&(n.dataset.boundChatComposer="1",n.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),eo()}));const o=document.getElementById("cmdAllowlistInput");o&&o.addEventListener("keydown",e=>{"Enter"===e.key&&Vn()});const a=document.getElementById("waAllowedNumbers");a&&a.addEventListener("input",$t);const s=document.getElementById("skillSearch");s&&s.addEventListener("input",e=>we(e.target.value));const i=document.getElementById("passthroughEngine");i&&i.addEventListener("change",()=>{so(),function(){const e=document.getElementById("passthroughEngine"),t=document.getElementById("passthroughModel");if(!e||!t)return;const n=e.value,o={cursor:[{value:"",label:"— default (opus-4.6-thinking) —"},{optgroup:"Recommended (No Rate Limits)"},{value:"gemini-3-flash",label:"🟢 Gemini 3 Flash (fastest)"},{value:"gemini-3-pro",label:"🟢 Gemini 3 Pro"},{value:"gemini-3.1-pro",label:"🟢 Gemini 3.1 Pro"},{value:"gpt-5.2-codex",label:"🟢 GPT-5.2 Codex"},{value:"gpt-5.3-codex",label:"🟢 GPT-5.3 Codex"},{optgroup:"Claude Models (May Hit Rate Limits)"},{value:"sonnet-4.5",label:"🟡 Claude 4.5 Sonnet"},{value:"sonnet-4.6",label:"🟡 Claude 4.6 Sonnet (current)"},{value:"opus-4.5",label:"🟡 Claude 4.5 Opus"},{value:"opus-4.6",label:"🟡 Claude 4.6 Opus"},{optgroup:"Thinking Models (Slower)"},{value:"sonnet-4.5-thinking",label:"Claude 4.5 Sonnet Thinking"},{value:"opus-4.6-thinking",label:"Claude 4.6 Opus Thinking"},{optgroup:"Other"},{value:"grok",label:"xAI Grok"},{value:"kimi-k2.5",label:"Moonshot Kimi K2.5"}],claude:[{value:"",label:"— default (Sonnet 4.6) —"},{optgroup:"Recommended"},{value:"sonnet",label:"🟢 Sonnet (alias for latest)"},{value:"Default",label:"🟢 Default (Sonnet 4.6)"},{optgroup:"Specific Versions"},{value:"claude-sonnet-4-6",label:"Sonnet 4.6 · Best for everyday tasks"},{value:"Opus",label:"Opus (Opus 4.6) · Most capable for complex work"},{value:"claude-opus-4-6",label:"Opus 4.6 · Most capable"},{value:"Haiku",label:"Haiku (Haiku 4.5) · Fastest for quick answers"},{value:"claude-haiku-4-5",label:"Haiku 4.5 · Fastest"},{optgroup:"Legacy"},{value:"claude-sonnet-4-5",label:"Sonnet 4.5 (legacy)"}],codex:[{value:"",label:"— default (gpt-5.3-codex) —"},{optgroup:"Recommended"},{value:"gpt-5.3-codex",label:"🟢 GPT-5.3 Codex (current)"},{value:"gpt-5.2-codex",label:"🟢 GPT-5.2 Codex"},{optgroup:"Specialized"},{value:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max (deep reasoning)"},{value:"gpt-5.2",label:"GPT-5.2 (general purpose)"},{value:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini (fast & cheap)"}],opencode:[{value:"",label:"— default —"},{optgroup:"Free Models 🎁"},{value:"opencode/big-pickle",label:"🆓 Big Pickle (Free)"},{value:"opencode/minimax-m2.5-free",label:"🆓 MiniMax M2.5 Free"},{value:"openai/gpt-5-nano",label:"🆓 GPT 5 Nano (Free)"},{optgroup:"Budget Models 💰"},{value:"openai/gpt-5.1-codex-mini",label:"💰 GPT 5.1 Codex Mini ($0.25/$2)"},{value:"google/gemini-3-flash",label:"💰 Gemini 3 Flash ($0.50/$3)"},{value:"anthropic/claude-haiku-4-5",label:"💰 Claude Haiku 4.5 ($1/$5)"},{optgroup:"Interesting Models 🎯"},{value:"moonshot/kimi-k2.5",label:"Kimi K2.5 ($0.60/$3)"},{value:"moonshot/kimi-k2-thinking",label:"Kimi K2 Thinking ($0.40/$2.50)"},{value:"alibaba/qwen3-coder-480b",label:"Qwen3 Coder 480B ($0.45/$1.50)"},{value:"zhipu/glm-5",label:"GLM 5 ($1/$3.20)"},{optgroup:"Premium Claude"},{value:"anthropic/claude-sonnet-4-6",label:"Claude Sonnet 4.6 ($3/$15)"},{value:"anthropic/claude-opus-4-6",label:"Claude Opus 4.6 ($5/$25)"},{optgroup:"Premium OpenAI"},{value:"openai/gpt-5.3-codex",label:"GPT 5.3 Codex ($1.75/$14)"},{value:"openai/gpt-5.2-codex",label:"GPT 5.2 Codex ($1.75/$14)"},{value:"openai/gpt-5.1-codex-max",label:"GPT 5.1 Codex Max ($1.25/$10)"},{optgroup:"Premium Google"},{value:"google/gemini-3.1-pro",label:"Gemini 3.1 Pro ($2/$12)"},{value:"google/gemini-3-pro",label:"Gemini 3 Pro ($2/$12)"}],gemini:[{value:"",label:"— default (gemini-3-flash-preview) —"},{optgroup:"Recommended (Latest)"},{value:"gemini-3-flash-preview",label:"🟢 Gemini 3 Flash Preview (current)"},{value:"gemini-3.1-pro-preview",label:"🟢 Gemini 3.1 Pro Preview"},{optgroup:"Gemini 2.5 Series"},{value:"gemini-2.5-pro",label:"Gemini 2.5 Pro"},{value:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{value:"gemini-2.5-flash-lite",label:"Gemini 2.5 Flash Lite (fastest)"}]};if(!n||!o[n])return void(t.style.display="none");t.style.display="inline-block",t.innerHTML="";let a=null;for(const s of o[n])if(s.optgroup)a=document.createElement("optgroup"),a.label=s.optgroup,t.appendChild(a);else{const e=document.createElement("option");e.value=s.value,e.textContent=s.label,a?a.appendChild(e):t.appendChild(e)}}(),ro()});const r=document.getElementById("chatProjectSelect");r&&r.addEventListener("change",so);const l=document.getElementById("passthroughModel");l&&l.addEventListener("change",()=>{ro()})},{once:!0});const Po={chat:On,"swarm-chat":x,swarm:_e,rt:Me,build:Io,files:Fn,dlq:Le,projects:To,contacts:Ee,agents:O,models:ze,engines:yo,skills:me,"run-skills":pe,waves:()=>{An(),document.getElementById("wavesView").style.display="block",jn("navWaves")},workflows:I,benchmarks:wo,"tool-matrix":ko,memory:bo,"cli-process":xo,services:L,prompts:de,settings:vo};document.addEventListener("click",e=>{const t=e.target.closest("[data-view]");if(t){const e=t.dataset.view,n=Po[e];return void(n&&(Mn()!==e?window.location.hash=e:n()))}const n=e.target.closest("[data-stab]");if(n){const e=n.dataset.stab;window.location.hash=`settings/${e}`,fo(e)}const o=e.target.closest("[data-toggle-child]");if(o){const e=o.dataset.toggleChild,t=o.parentElement&&o.parentElement.querySelector(e);t&&(t.style.display="none"===t.style.display?"block":"none")}const a=e.target.closest("[data-toggle-sibling]");a&&a.nextElementSibling&&a.nextElementSibling.classList.toggle(a.dataset.toggleSibling)}),Object.assign(window,{addAllowlistPattern:Vn,applyNewAgentToolPreset:ie,applyPromptPreset:se,bulkSetRoute:ae,cancelSkillForm:ge,chatAtAtInput:Xn,chatKeydown:Zn,clearChatHistory:to,filterSkills:we,loadAllUsage:xn,loadBenchmarkLeaderboard:async()=>(await Tn()).loadBenchmarkLeaderboard(),loadBenchmarks:async()=>(await Tn()).loadBenchmarks(),loadBenchmarkTasks:async()=>(await Tn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Tn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Tn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Tn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadBuildProjectPicker:Zt,loadFiles:po,loadOcStats:qn,loadRunSkills:ue,loadServices:M,loadSpending:bn,loadTelegramSessions:Ht,loadTgMessages:Ft,loadToolMatrix:mn,loadWaMessages:_t,onBuildProjectChange:tn,onChatProjectChange:en,pickFolder:Pn,renderWaContactRows:$t,resetSpending:wn,approveSkill:async function(e){try{await fetch("/api/skills/approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Approved"),Eo()}catch(t){i("Failed: "+t.message,"error")}},loadPendingApprovals:Eo,rejectSkill:async function(e){try{await fetch("/api/skills/reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Rejected"),Eo()}catch(t){i("Failed: "+t.message,"error")}},saveGlobalCaps:yn,saveGlobalFallback:ct,saveBgConsciousnessModel:ht,saveOpencodeSettings:pt,saveRTToken:gt,saveSkill:he,saveTgConfig:Dt,saveWaConfig:Nt,sendChat:eo,sendTestWebhook:Co,showAgents:O,showBenchmarks:wo,showBuild:Io,showChat:On,showContacts:Ee,showDLQ:Le,showFiles:Fn,showModels:ze,showProjects:To,showRT:Me,showRunSkills:pe,showServices:L,showSettings:vo,showSettingsTab:fo,showSkills:me,showSwarm:_e,showToolMatrix:ko,showMemoryView:bo,startCrew:H,startTgBridge:Gt,startWaBridge:Ot,stopTgBridge:zt,stopWaBridge:Rt,toggleAddSkill:ye,toggleBgConsciousness:lt,toggleCursorWaves:rt,toggleClaudeCode:st,toggleEmojiPicker:oe,updateSkillAuthFields:Ce,navigateTo:So,renderStatusBadge:p,showLoading:d,showEmpty:c,showError:l,loadContacts:Be,applyContactFilters:Te,applyToolPreset:ne,closePreviewPane:uo,deleteAgent:te,deleteSkill:ke,editSkill:xe,fetchBuiltinModels:Qe,fetchModels:Je,previewFile:mo,resetAgentSession:ee,restartAgentFromUI:un,restartService:N,runSkillFromUI:be,saveAgentFallback:Z,saveAgentVoice:X,saveAgentIdentity:Y,saveAgentModel:Q,saveAgentPrompt:J,saveAgentTools:W,saveBuiltinKey:We,saveCursorCliConfig:U,saveClaudeCodeConfig:K,saveGeminiCliConfig:q,saveKey:Ue,saveOpenCodeConfig:V,saveOpenCodeFallback:$,saveSearchTool:Ke,saveCodexConfig:G,setRoute:z,stopService:_,testBuiltinProvider:qe,testKey:Ve,testSearchTool:$e,toggleAgentBody:D,toggleKeyVis:Ge});
@@ -0,0 +1 @@
1
+ let t=null;async function e(){try{const t=await fetch("/api/health"),e=t.ok?await t.json():{ok:!1},n=await fetch("/api/agents"),o=n.ok?await n.json():{count:0},a=await fetch("/api/projects"),c=(a.ok?await a.json():{projects:[]}).projects||[],i=c.reduce((t,e)=>{var n;return t+((null==(n=e.roadmap)?void 0:n.pending)||0)},0),r=c.filter(t=>t.running).length,l=await fetch("/api/providers"),d=l.ok?await l.json():{providers:[]},s=(d.providers||[]).filter(t=>t.configured).map(t=>{var e;return"openai"===t.id?"GPT":"anthropic"===t.id?"Claude":"google"===t.id?"Gemini":"groq"===t.id?"Groq":"xai"===t.id?"Grok":"ollama"===t.id?"Local":null==(e=t.label)?void 0:e.split(" ")[0]}),u=document.getElementById("orchSystemStatus"),m=document.getElementById("orchModelStack"),h=document.getElementById("orchSwarmFill"),g=document.getElementById("orchSwarmPercent"),p=document.getElementById("orchActiveAgents"),y=document.getElementById("orchTaskQueue");u&&(e.ok?(u.textContent="● ONLINE",u.style.color="#10b981"):(u.textContent="● OFFLINE",u.style.color="#ef4444")),m&&(m.textContent=s.length>0?s.slice(0,3).join(" / "):"Not configured");const f=o.count||0,v=30,E=Math.min(100,Math.floor(f/v*100));if(h&&(h.style.width=`${E}%`),g&&(g.textContent=`${E}%`),p&&(p.textContent=f.toString()),y){const t=[];i>0&&t.push(`${i} pending`),r>0&&t.push(`${r} running`),y.textContent=t.length>0?t.join(", "):"0 pending"}}catch(t){console.error("[OrchestrationStatus] Update failed:",t);const e=document.getElementById("orchSystemStatus");e&&(e.textContent="● ERROR",e.style.color="#ef4444")}}function n(){e(),t&&clearInterval(t),t=setInterval(e,5e3)}function o(){t&&(clearInterval(t),t=null)}document.addEventListener("DOMContentLoaded",()=>{const t=document.getElementById("chatView");t&&t.classList.contains("active")&&n()});const a=document.getElementById("navChat");a&&a.addEventListener("click",()=>{setTimeout(n,100)});export{o as a,n as s,e as u};
@@ -0,0 +1 @@
1
+ import{g as e,p as t}from"./core-utils-CAVnDoe1.js";const n=[{id:"anthropic",label:"Anthropic",icon:"🟣",placeholder:"sk-ant-...",url:"https://console.anthropic.com/"},{id:"openai",label:"OpenAI",icon:"🟢",placeholder:"sk-...",url:"https://platform.openai.com/api-keys"},{id:"google",label:"Google (Gemini)",icon:"🔵",placeholder:"AIza...",url:"https://aistudio.google.com/apikey"},{id:"groq",label:"Groq",icon:"⚡",placeholder:"gsk_...",url:"https://console.groq.com/keys"},{id:"fireworks",label:"Fireworks AI",icon:"🎆",placeholder:"fw_...",url:"https://fireworks.ai/"},{id:"openrouter",label:"OpenRouter",icon:"🔀",placeholder:"sk-or-...",url:"https://openrouter.ai/keys"},{id:"xai",label:"xAI (Grok)",icon:"𝕏",placeholder:"xai-...",url:"https://console.x.ai/"},{id:"deepseek",label:"DeepSeek",icon:"🌊",placeholder:"sk-...",url:"https://platform.deepseek.com/"},{id:"mistral",label:"Mistral",icon:"🌀",placeholder:"...",url:"https://console.mistral.ai/api-keys"},{id:"cerebras",label:"Cerebras",icon:"🧠",placeholder:"csk-...",url:"https://cloud.cerebras.ai/"},{id:"nvidia",label:"NVIDIA NIM",icon:"🎮",placeholder:"nvapi-...",url:"https://build.nvidia.com/"},{id:"perplexity",label:"Perplexity",icon:"🔍",placeholder:"pplx-...",url:"https://www.perplexity.ai/settings/api"},{id:"ollama",label:"Ollama (local)",icon:"🏠",placeholder:"no key needed",url:"https://ollama.com/download"}],a=[{id:"claude-code",cmd:"claude",label:"Claude Code",desc:"Anthropic's CLI agent. Best for complex reasoning and multi-file refactors.",installUrl:"https://docs.anthropic.com/en/docs/claude-code/overview",authCmd:"claude auth",keyProvider:"anthropic"},{id:"codex",cmd:"codex",label:"Codex CLI",desc:"OpenAI's CLI agent. Sandboxed execution with full file write access.",installUrl:"https://github.com/openai/codex",authCmd:"codex auth",keyProvider:"openai"},{id:"crew-cli",cmd:"crew",label:"crew-cli",desc:"CrewSwarm's own 3-tier pipeline. Supports Anthropic, OpenAI, Gemini, Groq, DeepSeek, and more.",installUrl:null,authCmd:null,keyProvider:null},{id:"opencode",cmd:"opencode",label:"OpenCode",desc:"Multi-provider CLI agent. Supports OpenAI, Anthropic, Google, and more.",installUrl:"https://github.com/opencode-ai/opencode",authCmd:null,keyProvider:null},{id:"gemini-cli",cmd:"gemini",label:"Gemini CLI",desc:"Google's CLI agent. Fast inference with Gemini models.",installUrl:"https://github.com/google-gemini/gemini-cli",authCmd:"gemini auth",keyProvider:"google"},{id:"cursor",cmd:"cursor",label:"Cursor CLI",desc:"Cursor's agent mode via CLI. Requires Cursor IDE installed.",installUrl:"https://www.cursor.com/",authCmd:null,keyProvider:null}];let s=1,i=null,d={},l=[],c={};async function o(){try{const t=await e("/api/first-run-status"),n=new URLSearchParams(window.location.search).has("wizard");return!(!t.firstRun&&!n)&&(l=t.configuredProviders||[],s=1,d={},i=document.createElement("div"),i.id="setupWizardOverlay",i.className="setup-wizard-overlay",i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true"),i.setAttribute("aria-label","CrewSwarm setup wizard"),r(),document.body.appendChild(i),i.offsetHeight,i.classList.add("visible"),!0)}catch(t){return console.warn("[setup-wizard] Could not check first-run status:",t),!1}}function r(){if(!i)return;const e=function(){switch(s){case 1:default:return p();case 2:return function(){const e=document.createElement("div");e.className="setup-wizard-content";const t=document.createElement("div");t.className="setup-wizard-section-header",t.innerHTML='\n <h2 class="setup-wizard-section-title">API Keys</h2>\n <p class="setup-wizard-section-desc">\n Add keys for the providers you want to use. Already-configured keys are shown with a checkmark.\n Only new keys you enter will be saved &mdash; existing keys won\'t be touched.\n </p>\n ',e.appendChild(t);const a=document.createElement("div");a.className="setup-wizard-provider-list";for(const s of n){const e=l.includes(s.id),t=document.createElement("div");t.className="setup-wizard-provider-row",e&&t.classList.add("already-configured");const n=document.createElement("div");n.className="setup-wizard-provider-label";const i=document.createElement("span");i.className="setup-wizard-provider-icon",i.textContent=s.icon||"";const c=document.createElement("span");c.className="setup-wizard-provider-status",c.textContent=e?"✓":"",c.title=e?"Already configured":"Not configured";const o=document.createElement("span");o.className="setup-wizard-provider-name",o.textContent=s.label;const r=document.createElement("a");r.href=s.url,r.target="_blank",r.rel="noopener",r.className="setup-wizard-provider-link",r.textContent="Get key",r.setAttribute("aria-label",`Get API key for ${s.label}`),n.appendChild(i),n.appendChild(o),n.appendChild(c),n.appendChild(r);const p=document.createElement("div");p.className="setup-wizard-provider-input-wrap";const m=document.createElement("input");m.type="password",m.className="setup-wizard-provider-input",m.placeholder=e?"configured ✓":s.placeholder,m.autocomplete="off",m.spellcheck=!1,m.dataset.providerId=s.id,m.setAttribute("aria-label",`API key for ${s.label}`),d[s.id]&&(m.value=d[s.id]),m.addEventListener("input",()=>{const e=m.value.trim();e?(d[s.id]=e,t.classList.add("has-key")):(delete d[s.id],t.classList.remove("has-key")),u()});const h=document.createElement("button");h.type="button",h.className="setup-wizard-toggle-vis",h.textContent="👁",h.setAttribute("aria-label","Toggle key visibility"),h.addEventListener("click",()=>{m.type="password"===m.type?"text":"password"}),p.appendChild(m),p.appendChild(h),t.appendChild(n),t.appendChild(p),d[s.id]&&t.classList.add("has-key"),a.appendChild(t)}e.appendChild(a);const i=document.createElement("div");i.className="setup-wizard-error hidden",i.id="wizardProviderError",e.appendChild(i);const c=document.createElement("div");c.className="setup-wizard-actions";const o=document.createElement("button");o.className="setup-wizard-btn-ghost",o.textContent="Back",o.addEventListener("click",()=>{s=1,r()});const p=document.createElement("button");p.className="setup-wizard-btn-primary",p.id="wizardSaveBtn";const h=Object.keys(d).length>0,w=l.length>0;return p.textContent=h?"Save & Continue":"Continue",p.disabled=!h&&!w,p.addEventListener("click",m),c.appendChild(o),c.appendChild(p),e.appendChild(c),e}();case 3:return function(){var e;const t=document.createElement("div");t.className="setup-wizard-content";const i=document.createElement("div");i.className="setup-wizard-section-header",i.innerHTML='\n <h2 class="setup-wizard-section-title">CLI Engines</h2>\n <p class="setup-wizard-section-desc">\n CrewSwarm dispatches tasks to these CLI coding agents.\n You need at least one installed. Use the API keys from Step 2 to authenticate.\n </p>\n ',t.appendChild(i);const d=document.createElement("div");d.className="setup-wizard-engine-grid";const o=Object.values(c).filter(Boolean).length;for(const s of a){const t=!0===c[s.id],a="crew-cli"===s.id||t,i=document.createElement("div");i.className="setup-wizard-engine-card",a&&i.classList.add("available");const o=document.createElement("div");o.className="setup-wizard-engine-badge",a?(o.textContent="✓ Installed",o.classList.add("installed")):(o.textContent="Not found",o.classList.add("missing")),i.appendChild(o);const r=document.createElement("div");r.className="setup-wizard-engine-title",r.textContent=s.label,i.appendChild(r);const p=document.createElement("code");p.className="setup-wizard-engine-cmd",p.textContent=s.cmd,i.appendChild(p);const u=document.createElement("p");u.className="setup-wizard-engine-desc",u.textContent=s.desc,i.appendChild(u);const m=document.createElement("div");if(m.className="setup-wizard-engine-action",a&&s.authCmd){const e=document.createElement("span");e.className="setup-wizard-engine-auth-label",e.textContent="Auth:";const t=document.createElement("code");t.className="setup-wizard-engine-auth-cmd",t.textContent=s.authCmd,m.appendChild(e),m.appendChild(t)}else if(a&&s.keyProvider){const t=document.createElement("span");t.className="setup-wizard-engine-key-note";const a=(null==(e=n.find(e=>e.id===s.keyProvider))?void 0:e.label)||s.keyProvider,i=l.includes(s.keyProvider);t.textContent=i?`Uses ${a} key ✓`:`Needs ${a} key`,t.classList.add(i?"key-ok":"key-missing"),m.appendChild(t)}else if(!a&&s.installUrl){const e=document.createElement("a");e.href=s.installUrl,e.target="_blank",e.rel="noopener",e.className="setup-wizard-engine-install-btn",e.textContent="Install →",m.appendChild(e)}i.appendChild(m),d.appendChild(i)}if(t.appendChild(d),0===o&&Object.keys(c).length>0){const e=document.createElement("p");e.className="setup-wizard-engine-hint",e.innerHTML="No external CLI engines detected. <strong>crew-cli</strong> is built in and always available.",t.appendChild(e)}const p=document.createElement("div");p.className="setup-wizard-actions";const u=document.createElement("button");u.className="setup-wizard-btn-ghost",u.textContent="Back",u.addEventListener("click",()=>{s=2,r()});const m=document.createElement("button");return m.className="setup-wizard-btn-primary setup-wizard-btn-start",m.textContent="Launch Dashboard",m.addEventListener("click",h),p.appendChild(u),p.appendChild(m),t.appendChild(p),t}()}}();i.innerHTML="";const t=document.createElement("div");t.className="setup-wizard-card",t.appendChild(function(){const e=["Welcome","API Keys","Engines"],t=document.createElement("div");t.className="setup-wizard-steps",t.setAttribute("aria-label",`Step ${s} of 3`);for(let n=1;n<=3;n++){const a=document.createElement("button");a.className="setup-wizard-step-dot",a.setAttribute("aria-label",`Step ${n}`),a.tabIndex=-1,n===s&&a.classList.add("active"),n<s&&a.classList.add("completed");const i=document.createElement("span");i.className="setup-wizard-step-label",i.textContent=e[n-1];const d=document.createElement("div");if(d.className="setup-wizard-step",d.appendChild(a),d.appendChild(i),t.appendChild(d),n<3){const e=document.createElement("div");e.className="setup-wizard-step-line",n<s&&e.classList.add("completed"),t.appendChild(e)}}return t}()),t.appendChild(e),i.appendChild(t),requestAnimationFrame(()=>{t.classList.add("visible")})}function p(){const e=document.createElement("div");e.className="setup-wizard-content",e.innerHTML='\n <div class="setup-wizard-hero">\n <div class="setup-wizard-logo-ring">\n <img src="/favicon.png" alt="CrewSwarm" class="setup-wizard-logo" />\n </div>\n <h1 class="setup-wizard-title">Welcome to CrewSwarm</h1>\n <p class="setup-wizard-subtitle">\n Multi-agent orchestration for AI coding tools.<br>\n Let\'s get you set up in 2 minutes.\n </p>\n </div>\n <div class="setup-wizard-checklist">\n <div class="setup-wizard-check-item">\n <span class="setup-wizard-check-icon done">&check;</span>\n <span>Dashboard installed</span>\n </div>\n <div class="setup-wizard-check-item">\n <span class="setup-wizard-check-icon pending">&bull;</span>\n <span>Add API provider keys</span>\n </div>\n <div class="setup-wizard-check-item">\n <span class="setup-wizard-check-icon pending">&bull;</span>\n <span>Detect & configure CLI engines</span>\n </div>\n </div>\n ';const t=document.createElement("div");t.className="setup-wizard-actions";const n=document.createElement("button");n.className="setup-wizard-btn-primary",n.textContent="Get Started",n.addEventListener("click",()=>{s=2,r()});const a=document.createElement("button");return a.className="setup-wizard-btn-ghost",a.textContent="Skip setup",a.addEventListener("click",w),t.appendChild(n),t.appendChild(a),e.appendChild(t),e}function u(){const e=document.getElementById("wizardSaveBtn");if(!e)return;const t=Object.keys(d).length>0,n=l.length>0;e.textContent=t?"Save & Continue":"Continue",e.disabled=!t&&!n}async function m(){const n=document.getElementById("wizardSaveBtn"),a=document.getElementById("wizardProviderError"),i=Object.entries(d).filter(([,e])=>e&&e.length>0);if(i.length>0){n&&(n.disabled=!0,n.textContent="Saving..."),a&&a.classList.add("hidden");try{for(const[e,n]of i)await t("/api/providers/builtin/save",{providerId:e,apiKey:n})}catch(l){return a&&(a.textContent="Failed to save: "+(l.message||"Unknown error"),a.classList.remove("hidden")),void(n&&(n.disabled=!1,n.textContent="Save & Continue"))}}await async function(){try{const t=await e("/api/first-run-engines");c=t.engines||{}}catch{c={}}}(),s=3,r()}async function h(){const e=null==i?void 0:i.querySelector(".setup-wizard-btn-start");e&&(e.disabled=!0,e.textContent="Loading..."),w(),window.location.href=window.location.pathname}function w(){i&&(i.classList.remove("visible"),i.classList.add("dismissing"),i.addEventListener("transitionend",()=>{i.remove(),i=null},{once:!0}),setTimeout(()=>{i&&(i.remove(),i=null)},400))}export{o as c};
@@ -0,0 +1 @@
1
+ import{s as e,p as t,g as n,f as o,r as a,a as i,b as s,h as l}from"./core-utils-CAVnDoe1.js";let r=()=>{},d=()=>{},c=()=>{};function p(e={}){r=e.hideAllViews||r,d=e.setNavActive||d,c=e.refreshAgents||c}function u(){r(),document.getElementById("agentsView").classList.add("active"),d("navAgents"),i.activeTab="agents",s();const e=document.getElementById("agentsList")||document.getElementById("agentsView");e&&e.querySelector(".agent-card")?l("agents"):A()}let m=[],g={},f=[];const v={opencode:"⚡",cursor:"🖱",claudecode:"🤖","claude-code":"🤖",codex:"🟣",gemini:"🔵","gemini-cli":"🔵","crew-cli":"🔧","docker-sandbox":"🐳",direct:"💬"},y={opencode:"#22c55e",cursor:"#38bdf8",claudecode:"#f59e0b","claude-code":"#f59e0b",codex:"#a855f7",gemini:"#4285f4","gemini-cli":"#4285f4","crew-cli":"#10b981","docker-sandbox":"#0ea5e9",direct:"#6366f1"},h=[{id:"21m00Tcm4TlvDq8ikWAM",name:"Rachel"},{id:"pNInz6obpgDQGcFmaJgB",name:"Adam"},{id:"EXAVITQu4vr4xnSDxMaL",name:"Bella"},{id:"XB0fDUnXU5powFXDhCwa",name:"Charlotte"}],x=[{id:"en-US-Neural2-C",name:"US Female C"},{id:"en-US-Neural2-A",name:"US Male A"},{id:"en-GB-Neural2-A",name:"UK Female A"},{id:"en-AU-Neural2-A",name:"AU Female A"}],b=[...h,...x];function w(e=""){return e?b.some(t=>t.id===e)?e:"custom":""}function C(e=""){var t;return(null==(t=b.find(t=>t.id===e))?void 0:t.name)||e}const E=[{id:"write_file",desc:"Write files to disk (@@WRITE_FILE)"},{id:"read_file",desc:"Read files from disk (@@READ_FILE)"},{id:"mkdir",desc:"Create directories (@@MKDIR)"},{id:"run_cmd",desc:"Run whitelisted shell commands (@@RUN_CMD)"},{id:"git",desc:"Git & GitHub CLI operations"},{id:"web_search",desc:"Web search (Brave Search — @@WEB_SEARCH)"},{id:"web_fetch",desc:"Fetch URLs (@@WEB_FETCH)"},{id:"dispatch",desc:"Dispatch tasks to other agents"},{id:"telegram",desc:"Send Telegram messages (@@TELEGRAM)"}],k={"crew-qa":["read_file"],"crew-coder":["write_file","read_file","mkdir","run_cmd"],"crew-coder-front":["write_file","read_file","mkdir","run_cmd"],"crew-coder-back":["write_file","read_file","mkdir","run_cmd"],"crew-frontend":["write_file","read_file","mkdir","run_cmd"],"crew-fixer":["write_file","read_file","mkdir","run_cmd"],"crew-github":["read_file","run_cmd","git"],"crew-pm":["read_file","dispatch"],"crew-main":["read_file","write_file","run_cmd","dispatch"],"crew-security":["read_file","run_cmd"],"crew-copywriter":["write_file","read_file"],"crew-telegram":["telegram","read_file"],"crew-lead":["dispatch"]};function I(e){if(k[e])return k[e];for(const[t,n]of Object.entries(k))if(e.startsWith(t)||e.includes(t.replace("crew-","")))return n;return["read_file","write_file","mkdir","run_cmd"]}async function S(t){const n=I(t),o=document.getElementById("tools-"+t);o&&(o.querySelectorAll("input[type=checkbox]").forEach(e=>{e.checked=n.includes(e.dataset.tool)}),await ne(t),e("Role defaults applied for "+t))}async function A(){const e=document.getElementById("agentsList");e.innerHTML='<div class="meta" style="padding:20px;">Loading agents…</div>';try{const t=await n("/api/agents-config");m=t.allModels||[],g=t.modelsByProvider||{};const i=o(t.agents||[]);if(!i.length)return void(e.innerHTML='<div class="meta" style="padding:20px;">No agents found in config. Check ~/.crewswarm/crewswarm.json</div>');e.innerHTML="",i.forEach(t=>{const n=document.createElement("div");n.className="agent-card",n.id="agent-card-"+t.id;const o=m.map(e=>`<option value="${e}" ${e===t.model?"selected":""}>${e}</option>`).join(""),i=!t.model||m.includes(t.model)?"":`<option value="${t.model}" selected>${t.model} (custom)</option>`,s=a(t.liveness,t.ageSec),l=t.voice||{},r=l.voiceId||l.voice||"",d="custom"===w(r)?r:"";var c,p;n.innerHTML=`\n <div class="agent-card-header">\n <div class="agent-avatar" id="avatar-${t.id}" style="position:relative;">${t.emoji}</div>\n <div class="agent-meta">\n <div class="agent-id" style="display:flex;align-items:center;">${s}${t.id} <span class="meta" style="font-weight:400;margin-left:4px;">· ${t.name}</span>\n ${re[t.id]?'<span style="font-size:9px;font-weight:700;letter-spacing:0.04em;padding:1px 6px;border-radius:4px;margin-left:8px;'+(de[re[t.id]]||"")+'">'+re[t.id]+"</span>":""}\n <span id="coding-dot-${t.id}" style="display:none;margin-left:8px;align-items:center;gap:4px;font-size:11px;color:var(--accent);">\n <span style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--accent);animation:pulse 1s ease-in-out infinite;"></span>coding\n </span>\n </div>\n <div id="cur-model-${t.id}" style="margin-top:3px;display:flex;flex-wrap:wrap;align-items:center;gap:6px;">\n <span style="font-size:11px;font-family:'SF Mono',monospace;color:${le.has(t.model)?"var(--red-hi)":"var(--text-2)"};" title="Conversation model — used for direct replies and chat">\n ${le.has(t.model)?"⚠ ":"💬 "}${t.model||"(none)"}\n </span>\n ${t.useCursorCli?'<span style="font-size:11px;font-family:monospace;color:var(--purple);" title="Cursor CLI — routing tasks through Cursor agent subagents">⚡ cursor</span>':""}\n ${t.useClaudeCode?'<span style="font-size:11px;font-family:monospace;color:var(--green-hi);" title="Claude Code CLI — routing tasks through claude -p">🤖 claude</span>':""}\n ${t.useCodex?'<span style="font-size:11px;font-family:monospace;color:var(--purple);" title="Codex CLI — routing tasks through codex exec">🟣 '+(t.codexModel||"codex")+"</span>":""}\n ${t.useGeminiCli?'<span style="font-size:11px;font-family:monospace;color:#4285f4;" title="Gemini CLI — routing tasks through gemini -p">🔵 gemini</span>':""}\n ${t.useCrewCLI?'<span style="font-size:11px;font-family:monospace;color:#10b981;" title="Crew CLI — routing tasks through crew-cli native agents">🔧 '+(t.crewCliModel||"crew-cli")+"</span>":""}\n ${!t.opencodeModel||t.useCursorCli||t.useClaudeCode||t.useCodex||t.useGeminiCli||t.useCrewCLI?"":'<span style="font-size:11px;font-family:monospace;color:'+(le.has(t.opencodeModel)?"var(--red-hi)":"var(--green-hi)")+';" title="OpenCode model — used when routing tasks through OpenCode CLI">⚡ '+t.opencodeModel+"</span>"}\n ${le.has(t.model)?'<span style="font-size:10px;font-weight:600;color:var(--red-hi);background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);padding:1px 6px;border-radius:4px;">BROKEN — REASSIGN</span>':""}\n </div>\n </div>\n <button class="btn-ghost" style="font-size:11px; padding:4px 10px;" data-action="toggleAgentBody" data-arg="${t.id}">Edit ▾</button>\n <button class="btn-ghost" style="font-size:11px; padding:4px 10px; color:var(--red); border-color:rgba(248,113,113,0.3);" data-action="deleteAgent" data-arg="${t.id}">✕</button>\n </div>\n <div class="agent-body" id="body-${t.id}" style="display:none;">\n <div>\n <div class="field-label" style="display:flex;align-items:center;gap:8px;">\n <span>💬 Conversation Model</span>\n <span style="font-size:10px;font-weight:400;color:var(--text-3);">Used for direct replies, planning, and chat. <strong style="color:var(--text-2);">Not used when OpenCode is enabled.</strong></span>\n </div>\n ${le.has(t.model)?'<div style="font-size:11px;color:var(--red-hi);background:rgba(239,68,68,0.08);border:1px solid rgba(239,68,68,0.25);border-radius:5px;padding:6px 10px;margin-bottom:8px;">⚠ Current model <code>'+t.model+"</code> is broken (returns empty responses). Please reassign.</div>":""}\n <div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">\n <select id="model-${t.id}" style="flex:1; min-width:200px;" onchange="syncModelText('${t.id}')">${i}${o}</select>\n <input id="modeltext-${t.id}" type="text" placeholder="or type provider/model…" value="${t.model||""}" style="flex:1; min-width:160px; font-size:12px;" oninput="syncModelSelect('${t.id}')" />\n <button data-action="saveAgentModel" data-arg="${t.id}" class="btn-green" style="white-space:nowrap;">Save</button>\n </div>\n <div style="margin-top:8px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">\n <span style="font-size:11px;color:var(--text-3);white-space:nowrap;">↩ Fallback:</span>\n ${(()=>{const e=t.fallbackModel&&!m.includes(t.fallbackModel)?`<option value="${t.fallbackModel}" selected>${t.fallbackModel} (custom)</option>`:"",n=m.map(e=>`<option value="${e}" ${e===t.fallbackModel?"selected":""}>${e}</option>`).join("");return`<select id="fmodel-${t.id}" style="flex:1;min-width:180px;font-size:11px;" onchange="syncFallbackText('${t.id}')"><option value="">— none —</option>${e}${n}</select>`})()}\n <input id="fallback-${t.id}" type="text" placeholder="or type any model…"\n value="${t.fallbackModel||""}"\n style="flex:1; min-width:140px; font-size:11px; color:var(--text-2);"\n oninput="syncFallbackSelect('${t.id}')" />\n <button data-action="saveAgentFallback" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:11px;">Save</button>\n </div>\n </div>\n <div>\n <div class="field-label">Display name &amp; emoji</div>\n <div style="display:flex; gap:8px;">\n <input id="aname-${t.id}" type="text" value="${t.name}" placeholder="Display name" style="flex:1;" />\n <div class="emoji-picker-wrap">\n <button type="button" class="emoji-btn" id="aemoji-btn-${t.id}" data-action="toggleEmojiPicker" data-arg="${t.id}" title="Pick emoji">${t.emoji||"🤖"}</button>\n <input type="hidden" id="aemoji-${t.id}" value="${t.emoji||"🤖"}" />\n <div class="emoji-picker-panel" id="aemoji-panel-${t.id}">\n <div class="emoji-grid" id="aemoji-grid-${t.id}"></div>\n </div>\n </div>\n <button data-action="saveAgentIdentity" data-arg="${t.id}" class="btn-ghost">Save</button>\n </div>\n <div style="margin-top:8px;">\n <div class="field-label" style="margin-bottom:4px;">Role / Theme <span style="font-weight:400; color:var(--text-3); font-size:11px;">— used by PM router to assign tasks (e.g. "iOS/Swift developer (SwiftUI, UIKit)")</span></div>\n <input id="atheme-${t.id}" type="text" value="${t.theme||""}" placeholder="Describe what this agent specialises in..." style="width:100%;" />\n </div>\n <div style="margin-top:10px; padding:10px; background:var(--surface-2); border:1px solid var(--border); border-radius:8px;">\n <div class="field-label" style="margin-bottom:6px;">Voice / TTS</div>\n <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center;">\n <select id="voice-provider-${t.id}" style="min-width:140px; flex:0 0 160px;">\n <option value="auto" ${"auto"===(l.provider||"auto")?"selected":""}>Auto provider</option>\n <option value="elevenlabs" ${"elevenlabs"===l.provider?"selected":""}>ElevenLabs</option>\n <option value="google" ${"google"===l.provider?"selected":""}>Google TTS</option>\n </select>\n <select id="voice-preset-${t.id}" style="flex:1; min-width:220px;" onchange="toggleAgentVoiceCustom('${t.id}')">\n ${function(e=""){const t=h.map(t=>`<option value="${t.id}" ${e===t.id?"selected":""}>${t.name}</option>`).join(""),n=x.map(t=>`<option value="${t.id}" ${e===t.id?"selected":""}>${t.name}</option>`).join("");return`\n <option value="" ${e?"":"selected"}>Use default voice</option>\n <optgroup label="ElevenLabs">${t}</optgroup>\n <optgroup label="Google TTS">${n}</optgroup>\n <option value="custom" ${"custom"===w(e)?"selected":""}>Custom voice ID…</option>\n `}(r)}\n </select>\n <input id="voice-custom-${t.id}" type="text" placeholder="Custom voice ID or Google voice name"\n value="${d}"\n style="flex:1; min-width:200px; display:${"custom"===w(r)?"block":"none"};" />\n <button data-action="saveAgentVoice" data-arg="${t.id}" class="btn-ghost">Save voice</button>\n </div>\n <div class="meta" style="margin-top:6px;">Used by Telegram and WhatsApp TTS when voice replies are enabled for the recipient.</div>\n </div>\n </div>\n <div>\n <div style="display:flex; align-items:center; gap:10px; margin-bottom:6px;">\n <div class="field-label" style="margin:0;">System Prompt</div>\n ${t.systemPrompt?"":'<span style="font-size:11px; color:var(--yellow);">⚠ No prompt set — agent has no role context</span>'}\n <select style="font-size:11px; padding:3px 8px; margin-left:auto;" onchange="applyAgentPromptPreset('${t.id}', this.value); this.value=''">\n ${c="Presets…",p=oe.map(function(e){return'<option value="'+e.value+'">'+e.label+"</option>"}).join(""),'<option value="">'+c+"</option>"+p}\n </select>\n </div>\n <textarea id="prompt-${t.id}" rows="5" placeholder="Describe this agent's role. It's injected at the top of every task.">${t.systemPrompt||""}</textarea>\n <div style="margin-top:8px; display:flex; gap:8px;">\n <button data-action="saveAgentPrompt" data-arg="${t.id}" class="btn-ghost">Save prompt</button>\n </div>\n </div>\n <div style="border-top:1px solid var(--border); padding-top:10px;">\n <div class="field-label" style="margin-bottom:8px;">Session</div>\n <div style="display:flex; gap:8px; align-items:center; margin-bottom:12px;">\n <button data-action="resetAgentSession" data-arg="${t.id}" class="btn-ghost" style="font-size:12px;">↺ Reset context window</button>\n <span style="font-size:11px; color:var(--text-3);">Clears accumulated token context. Shared memory is re-injected on next task.</span>\n </div>\n </div>\n <div style="border-top:1px solid var(--border); padding-top:10px;">\n <div class="field-label" style="display:flex; align-items:center; gap:8px; margin-bottom:4px;">\n <span>crewswarm — Agent Tools</span>\n <span style="font-size:10px; font-weight:600; color:var(--accent); padding:2px 6px; border-radius:4px; background:rgba(56,189,248,0.08); border:1px solid rgba(56,189,248,0.25);">gateway-bridge</span>\n </div>\n <div class="meta" style="margin-bottom:10px; font-size:11px;">Controls which tools this agent can execute on disk and network. Enforced by gateway-bridge on every task — only checked tools are active.</div>\n <div id="tools-${t.id}" style="display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); gap:6px; margin-bottom:12px;">\n ${E.map(e=>`\n <label style="display:flex; align-items:flex-start; gap:7px; font-size:12px; color:var(--text-2); cursor:pointer; padding:6px 8px; border-radius:5px; border:1px solid var(--border); background:var(--bg-card2);">\n <input type="checkbox" data-tool="${e.id}" ${(t.alsoAllow||[]).includes(e.id)?"checked":""} style="accent-color:var(--accent); margin-top:2px; flex-shrink:0;" />\n <div>\n <code style="font-size:11px; color:var(--text-1);">${e.id}</code>\n <div style="font-size:10px; color:var(--text-3); margin-top:2px; line-height:1.3;">${e.desc}</div>\n </div>\n </label>\n `).join("")}\n </div>\n <div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <button data-action="saveAgentTools" data-arg="${t.id}" class="btn-ghost" style="font-size:12px;">Save tools</button>\n <button data-action="applyToolPreset" data-arg="${t.id}" class="btn-ghost" style="font-size:12px; color:var(--text-3);">↩ Role defaults</button>\n </div>\n <div class="meta">Workspace: <code style="font-size:11px;">${t.workspace}</code></div>\n </div>\n <div style="border-top:1px solid var(--border); padding-top:10px;">\n <div class="field-label" style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">\n <span>⚡ Execution Route</span>\n <span style="font-size:10px; font-weight:600; color:var(--text-3); padding:2px 6px; border-radius:4px; background:var(--surface-2);">pick one — mutually exclusive</span>\n </div>\n <div id="engine-buttons-${t.id}" style="display:flex; gap:6px; margin-bottom:10px; flex-wrap:wrap;">\n \x3c!-- Dynamically populated from /api/engines --\x3e\n </div>\n <div id="loop-row-${t.id}" style="display:${t.useOpenCode||t.useCursorCli||t.useClaudeCode||t.useCodex||t.useGeminiCli||t.useCrewCLI?"flex":"none"}; align-items:center; gap:10px; margin-bottom:10px; padding:8px 10px; background:var(--surface-2); border-radius:8px; border:1px solid var(--border);">\n <label style="display:flex; align-items:center; gap:8px; cursor:pointer; flex:1;">\n <input type="checkbox" id="loop-toggle-${t.id}" ${t.opencodeLoop?"checked":""} onchange="saveAgentLoop('${t.id}')" style="width:14px; height:14px; cursor:pointer;" />\n <span style="font-size:12px; font-weight:600; color:var(--text-1);">🔁 Ouroboros Loop</span>\n <span style="font-size:11px; color:var(--text-3);">LLM decomposes task → engine runs each step → feeds result back until DONE</span>\n </label>\n <div style="display:flex; align-items:center; gap:6px;">\n <span style="font-size:11px; color:var(--text-3); white-space:nowrap;">Max rounds:</span>\n <input type="number" id="loop-rounds-${t.id}" min="1" max="20" value="${t.opencodeLoopMaxRounds||10}" class="inp-xs" style="width:52px;text-align:center;" onchange="saveAgentLoop('${t.id}')" />\n </div>\n </div>\n <div id="oc-model-row-${t.id}" style="display:${t.useOpenCode&&!t.useCursorCli?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:6px;">\n <select id="oc-model-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncOcModelText('${t.id}')"></select>\n <input id="oc-modeltext-${t.id}" type="text" placeholder="opencode/model…" value="${t.opencodeModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveOpenCodeConfig" data-arg="${t.id}" class="btn-green" style="white-space:nowrap; font-size:12px;">Save</button>\n </div>\n <div id="oc-fallback-row-${t.id}" style="display:${t.useOpenCode&&!t.useCursorCli?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <span style="font-size:11px; color:var(--text-3); white-space:nowrap;">↩ Fallback:</span>\n <select id="oc-fallback-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncOcFallbackText('${t.id}')"></select>\n <input id="oc-fallback-${t.id}" type="text" placeholder="opencode/model or leave blank" value="${t.opencodeFallbackModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveOpenCodeFallback" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:12px;">Save</button>\n </div>\n <div id="cursor-model-row-${t.id}" style="display:${t.useCursorCli?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <select id="cursor-model-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncCursorModelText('${t.id}')"></select>\n <input id="cursor-model-txt-${t.id}" type="text" placeholder="sonnet-4.6 or leave blank for auto" value="${t.cursorCliModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveCursorCliConfig" data-arg="${t.id}" class="btn-sky" style="white-space:nowrap; font-size:12px;">Save</button>\n </div>\n <div id="claudecode-model-row-${t.id}" style="display:${t.useClaudeCode?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <select id="claudecode-model-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncClaudeCodeModelText('${t.id}')">\n <option value="">— auto (claude-sonnet-4-5) —</option>\n <option value="claude-opus-4-5" ${"claude-opus-4-5"===(t.claudeCodeModel||"")?"selected":""}>claude-opus-4-5 — best reasoning</option>\n <option value="claude-sonnet-4-5" ${"claude-sonnet-4-5"===(t.claudeCodeModel||"")?"selected":""}>claude-sonnet-4-5 — best coding</option>\n <option value="claude-haiku-4-5" ${"claude-haiku-4-5"===(t.claudeCodeModel||"")?"selected":""}>claude-haiku-4-5 — fast &amp; cheap</option>\n </select>\n <input id="claudecode-model-txt-${t.id}" type="text" placeholder="claude-sonnet-4-5 or leave blank" value="${t.claudeCodeModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveClaudeCodeConfig" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:12px; color:#f59e0b; border-color:rgba(245,158,11,0.3);">Save</button>\n </div>\n <div id="codex-model-row-${t.id}" style="display:${t.useCodex?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <select id="codex-model-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncCodexModelText('${t.id}')">\n <option value="">— auto (Codex default) —</option>\n <option value="gpt-5.3-codex" ${"gpt-5.3-codex"===(t.codexModel||"")?"selected":""}>gpt-5.3-codex</option>\n <option value="gpt-5.2-codex" ${"gpt-5.2-codex"===(t.codexModel||"")?"selected":""}>gpt-5.2-codex</option>\n <option value="gpt-5.1-codex" ${"gpt-5.1-codex"===(t.codexModel||"")?"selected":""}>gpt-5.1-codex</option>\n <option value="gpt-5.1-codex-mini" ${"gpt-5.1-codex-mini"===(t.codexModel||"")?"selected":""}>gpt-5.1-codex-mini</option>\n <option value="codex-mini" ${"codex-mini"===(t.codexModel||"")?"selected":""}>codex-mini</option>\n </select>\n <input id="codex-model-txt-${t.id}" type="text" placeholder="gpt-5.3-codex or leave blank for auto" value="${t.codexModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveCodexConfig" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:12px; color:#a855f7; border-color:rgba(168,85,247,0.3);">Save</button>\n </div>\n <div id="gemini-model-row-${t.id}" style="display:${t.useGeminiCli?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">\n <select id="gemini-model-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncGeminiModelText('${t.id}')">\n <option value="">— auto (gemini-2.5-flash) —</option>\n <option value="gemini-2.5-flash" ${"gemini-2.5-flash"===(t.geminiCliModel||"")?"selected":""}>gemini-2.5-flash — fast &amp; cheap</option>\n <option value="gemini-2.5-pro" ${"gemini-2.5-pro"===(t.geminiCliModel||"")?"selected":""}>gemini-2.5-pro — best reasoning</option>\n <option value="gemini-2.0-flash" ${"gemini-2.0-flash"===(t.geminiCliModel||"")?"selected":""}>gemini-2.0-flash — ultra fast</option>\n </select>\n <input id="gemini-model-txt-${t.id}" type="text" placeholder="gemini-2.5-flash or leave blank for auto" value="${t.geminiCliModel||""}" style="flex:1; min-width:160px; font-size:12px;" />\n <button data-action="saveGeminiCliConfig" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:12px; color:#4285f4; border-color:rgba(66,133,244,0.3);">Save</button>\n </div>\n <div id="crew-cli-config-row-${t.id}" style="display:${t.useCrewCLI?"flex":"none"}; gap:8px; align-items:center; flex-wrap:wrap; padding:10px; background:var(--surface-2); border-radius:8px; border:1px solid var(--border); margin-bottom:10px;">\n <span style="font-size:12px; font-weight:600; color:var(--text-1);">🔧 Crew CLI Mode Active</span>\n <select id="crew-cli-model-sel-${t.id}" style="flex:1; min-width:200px; font-size:12px;" onchange="syncCrewCliModelText('${t.id}')"></select>\n <input id="crew-cli-model-txt-${t.id}" type="text" placeholder="provider/model or leave blank for default" value="${t.crewCliModel||""}" style="flex:1; min-width:180px; font-size:12px;" />\n <button data-action="saveCrewCLIConfig" data-arg="${t.id}" class="btn-ghost" style="white-space:nowrap; font-size:12px; color:#10b981; border-color:rgba(16,185,129,0.3);">Save</button>\n </div>\n </div>\n <div style="border-top:1px solid var(--border); padding:10px 16px; display:flex; align-items:center; justify-content:space-between; gap:8px;">\n <div style="font-size:11px; color:var(--text-3);">\n Session context accumulates over time. Reset clears the conversation history and re-injects shared memory.\n </div>\n <button data-action="resetAgentSession" data-arg="${t.id}" class="btn-ghost" style="font-size:12px; white-space:nowrap; color:var(--amber); border-color:rgba(245,158,11,0.3);">↺ Reset session</button>\n </div>\n </div>\n `,e.appendChild(n)}),i.forEach(e=>{const t=document.getElementById("model-"+e.id),n=re[e.id]||null;t&&pe("model-"+e.id,e.model,n)}),await async function(e){try{const t=await n("/api/engines");f=t.engines||[],e.forEach(e=>{const t=document.getElementById(`engine-buttons-${e.id}`);if(!t)return;t.innerHTML="";const n=e.useOpenCode?"opencode":e.useCursorCli?"cursor":e.useClaudeCode?"claude-code":e.useCodex?"codex":e.useGeminiCli?"gemini-cli":e.useCrewCLI?"crew-cli":"direct",o=$(e.id,"direct","💬 Direct API","direct"===n,"#6366f1");t.appendChild(o),f.filter(e=>e.ready).sort((e,t)=>String(e.label||e.id).localeCompare(String(t.label||t.id))).forEach(o=>{const a=v[o.id]||"🔧",i=y[o.id]||o.color||"#6b7280",s=`${a} ${o.label}`,l=o.installUrl?"(ready)":"",r=$(e.id,o.id,s,n===o.id,i,l);t.appendChild(r)})})}catch(t){console.error("Failed to load engines:",t)}}(i),async function(){if(P)return P;try{const e=await fetch("/api/opencode-models"),t=await e.json();P=Array.isArray(t.models)?t.models:[]}catch{P=[]}return P}().then(()=>{i.forEach(e=>{W("oc-model-"+e.id,e.opencodeModel||""),W("oc-fallback-sel-"+e.id,e.opencodeFallbackModel||""),function(e,t){const n=document.getElementById(e);if(!n)return;n.innerHTML=N.map(e=>'<option value="'+e.id+'"'+(e.id===(t||"")?" selected":"")+">"+e.label+"</option>").join("")}("cursor-model-sel-"+e.id,e.cursorCliModel||""),function(e,t){const n=document.getElementById(e);if(!n)return;n.innerHTML='<option value="">— auto / default —</option>';const o={};(m||[]).forEach(e=>{const t=e.includes("/")?e.split("/")[0]:"other";o[t]||(o[t]=[]),o[t].push(e)});for(const[a,i]of Object.entries(o)){const e=document.createElement("optgroup");e.label=a.toUpperCase(),i.forEach(n=>{const o=document.createElement("option");o.value=n,o.textContent=n,n===t&&(o.selected=!0),e.appendChild(o)}),n.appendChild(e)}if(t&&!n.value){const e=document.createElement("option");e.value=t,e.textContent=t+" (custom)",e.selected=!0,n.prepend(e)}}("crew-cli-model-sel-"+e.id,e.crewCliModel||"")})})}catch(t){e.innerHTML='<div class="meta" style="padding:20px; color:var(--red);">Error: '+t.message+"</div>"}}function $(e,t,n,o,a,i=""){const s=document.createElement("button");s.id=`route-${t}-${e}`,s.dataset.action="setRoute",s.dataset.arg=e,s.dataset.arg2=t;const l=o?a:"var(--border)",r=o?`${a}20`:"var(--surface-2)",d=o?a:"var(--text-2)";return s.style.cssText=`\n font-size:11px; font-weight:600; padding:5px 12px; border-radius:6px; cursor:pointer;\n border:1px solid ${l}; background:${r}; color:${d};\n `,s.innerHTML=n+(i?` <span style="font-size:10px; font-weight:400; opacity:0.7;">${i}</span>`:""),s}function R(e){const t=document.getElementById("body-"+e);t.style.display="none"===t.style.display?"grid":"none"}async function B(n){if(!confirm('Delete agent "'+n+'"? This cannot be undone.'))return;const o=document.getElementById("agent-card-"+n);o&&(o.style.opacity="0.3");try{await t("/api/agents-config/delete",{agentId:n}),o&&o.remove(),e("Agent "+n+" deleted"),await A()}catch(a){o&&(o.style.opacity="1"),e("Delete failed: "+a.message,!0)}}async function T(n){var o,a,i;const s=(null==(o=document.getElementById("voice-provider-"+n))?void 0:o.value)||"auto",l=(null==(a=document.getElementById("voice-preset-"+n))?void 0:a.value)||"",r=(null==(i=document.getElementById("voice-custom-"+n))?void 0:i.value.trim())||"",d="custom"===l?r:l,c=d?{provider:s,voiceId:d,voice:d,name:C(d)}:null;try{await t("/api/agents-config/update",{agentId:n,voice:c}),e(c?`Voice saved for ${n}`:`Voice reset to default for ${n}`)}catch(p){e("Failed: "+p.message,!0)}}async function M(n){if(confirm("Reset context window for "+n+"?\\n\\nThis clears the agent's accumulated conversation history. Shared memory files will be re-injected on the next task.")){e("Resetting "+n+" session...");try{await t("/api/agents-config/reset-session",{agentId:n}),e(n+" session reset")}catch(o){e("Reset failed: "+o.message,!0)}}}function L(e,t,n){const o=document.getElementById("cur-model-"+e);if(!o)return;const a=le.has(t),i=n&&le.has(n);o.innerHTML=`<span style="font-size:11px;font-family:'SF Mono',monospace;color:${a?"var(--red-hi)":"var(--text-2)"};" title="Conversation model">${a?"⚠ ":"💬 "}${t||"(none)"}</span>`+(n?`<span style="font-size:11px;font-family:'SF Mono',monospace;color:${i?"var(--red-hi)":"var(--green-hi)"};" title="OpenCode model">⚡ ${n}</span>`:"")+(a?'<span style="font-size:10px;font-weight:600;color:var(--red-hi);background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);padding:1px 6px;border-radius:4px;">BROKEN — REASSIGN</span>':"")}async function O(n){var o;const a=document.getElementById("modeltext-"+n),i=document.getElementById("model-"+n),s=a&&a.value.trim()||i&&i.value||"";if(s)if(le.has(s))e("⚠ That model returns empty responses — choose another",!0);else try{await t("/api/agents-config/update",{agentId:n,model:s});L(n,s,(null==(o=document.getElementById("oc-modeltext-"+n))?void 0:o.value.trim())||""),e(`${n} → ${s}`)}catch(l){e("Failed: "+l.message,!0)}else e("Select or type a model",!0)}async function F(n){const o=document.getElementById("fallback-"+n),a=(null==o?void 0:o.value.trim())||"";try{await t("/api/agents-config/update",{agentId:n,fallbackModel:a}),e(a?`Fallback set: ${a}`:`Fallback cleared for ${n}`)}catch(i){e("Failed: "+i.message,!0)}}window.syncModelText=function(e){const t=document.getElementById("model-"+e),n=document.getElementById("modeltext-"+e);n&&(n.value=t.value)},window.syncModelSelect=function(e){const t=document.getElementById("modeltext-"+e),n=document.getElementById("model-"+e);if(!n)return;const o=t.value.trim(),a=[...n.options].find(e=>e.value===o);n.value=a?o:""},window.syncFallbackText=function(e){const t=document.getElementById("fmodel-"+e),n=document.getElementById("fallback-"+e);n&&(n.value=t.value)},window.syncFallbackSelect=function(e){const t=document.getElementById("fallback-"+e),n=document.getElementById("fmodel-"+e);if(!n)return;const o=t.value.trim(),a=[...n.options].find(e=>e.value===o);n.value=a?o:""},window.toggleAgentVoiceCustom=function(e){const t=document.getElementById("voice-preset-"+e),n=document.getElementById("voice-custom-"+e);t&&n&&(n.style.display="custom"===t.value?"block":"none")};let P=null;const _={"opencode/big-pickle":"Big Pickle (Stealth)","opencode/trinity-large-preview-free":"Trinity Large Preview (Stealth)","opencode/gpt-5":"GPT 5","opencode/gpt-5-codex":"GPT 5 Codex","opencode/gpt-5-nano":"GPT 5 Nano","opencode/gpt-5.1":"GPT 5.1","opencode/gpt-5.1-codex":"GPT 5.1 Codex","opencode/gpt-5.1-codex-max":"GPT 5.1 Codex Max","opencode/gpt-5.1-codex-mini":"GPT 5.1 Codex Mini","opencode/gpt-5.2":"GPT 5.2","opencode/gpt-5.2-codex":"GPT 5.2 Codex","opencode/alpha-gpt-5.3-codex":"GPT 5.3 Codex (alpha)","opencode/alpha-gpt-5.4":"GPT 5.4 (alpha)","opencode/claude-sonnet-4":"Claude Sonnet 4","opencode/claude-sonnet-4-5":"Claude Sonnet 4.5","opencode/claude-sonnet-4-6":"Claude Sonnet 4.6","opencode/claude-opus-4-1":"Claude Opus 4.1","opencode/claude-opus-4-5":"Claude Opus 4.5","opencode/claude-opus-4-6":"Claude Opus 4.6","opencode/claude-haiku-4-5":"Claude Haiku 4.5","opencode/claude-3-5-haiku":"Claude 3.5 Haiku","opencode/gemini-3-flash":"Gemini 3 Flash","opencode/gemini-3-pro":"Gemini 3 Pro","opencode/gemini-3.1-pro":"Gemini 3.1 Pro","opencode/kimi-k2":"Kimi K2","opencode/kimi-k2-thinking":"Kimi K2 Thinking","opencode/kimi-k2.5":"Kimi K2.5","opencode/kimi-k2.5-free":"Kimi K2.5 Free","opencode/glm-4.6":"GLM 4.6 (Z.ai)","opencode/glm-4.7":"GLM 4.7 (Z.ai)","opencode/glm-5":"GLM 5 (Z.ai)","opencode/glm-5-free":"GLM 5 Free (Z.ai)","opencode/minimax-m2.1":"MiniMax M2.1","opencode/minimax-m2.1-free":"MiniMax M2.1 Free","opencode/minimax-m2.5":"MiniMax M2.5","opencode/minimax-m2.5-free":"MiniMax M2.5 Free"};function W(e,t){const n=document.getElementById(e);if(!n)return;n.innerHTML='<option value="">— select model —</option>';const o=(P||[]).map(e=>"string"==typeof e?e:e.provider?e.provider+"/"+e.id:e.id||e.name||String(e)),a=[...new Set([...o,...m||[]])].filter(Boolean),i={};a.forEach(e=>{const t=e.includes("/")?e.split("/")[0]:"other";i[t]||(i[t]=[]),i[t].push(e)});for(const[s,l]of Object.entries(i)){const e=document.createElement("optgroup");e.label=s.toUpperCase(),l.forEach(n=>{const o=document.createElement("option");o.value=n,o.textContent=_[n]||n,n===t&&(o.selected=!0),e.appendChild(o)}),n.appendChild(e)}if(t&&!n.value){const e=document.createElement("option");e.value=t,e.textContent=(_[t]||t)+" (custom)",e.selected=!0,n.prepend(e)}}const N=[{id:"",label:"— auto (subscription default) —"},{id:"sonnet-4.5-thinking",label:"Claude 4.5 Sonnet (Thinking) — default"},{id:"opus-4.6-thinking",label:"Claude 4.6 Opus (Thinking) — best reasoning"},{id:"opus-4.6",label:"Claude 4.6 Opus"},{id:"sonnet-4.6-thinking",label:"Claude 4.6 Sonnet (Thinking)"},{id:"sonnet-4.6",label:"Claude 4.6 Sonnet — best coding"},{id:"sonnet-4.5",label:"Claude 4.5 Sonnet"},{id:"gpt-5.3-codex-xhigh",label:"GPT-5.3 Codex XHigh"},{id:"gpt-5.3-codex-high",label:"GPT-5.3 Codex High"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.3-codex-fast",label:"GPT-5.3 Codex Fast"},{id:"gpt-5.2",label:"GPT-5.2"},{id:"gemini-3.1-pro",label:"Gemini 3.1 Pro"},{id:"gemini-3-flash",label:"Gemini 3 Flash"},{id:"grok",label:"Grok"},{id:"kimi-k2.5",label:"Kimi K2.5"}];async function j(n,o){const a={agentId:n,useOpenCode:!1,useCursorCli:!1,useClaudeCode:!1,useCodex:!1,useGeminiCli:!1,useCrewCLI:!1,...{direct:{},opencode:{useOpenCode:!0},cursor:{useCursorCli:!0},"claude-code":{useClaudeCode:!0},claudecode:{useClaudeCode:!0},codex:{useCodex:!0},"gemini-cli":{useGeminiCli:!0},gemini:{useGeminiCli:!0},"crew-cli":{useCrewCLI:!0}}[o]||{}},i=document.getElementById(`engine-buttons-${n}`);if(i){i.querySelectorAll("button").forEach(e=>{const t=e.dataset.arg2,n=f.find(e=>e.id===t)||{},a=y[t]||n.color||"#6b7280",i=t===o;e.style.borderColor=i?a:"var(--border)",e.style.background=i?`${a}20`:"var(--surface-2)",e.style.color=i?a:"var(--text-2)"})}const s="direct"!==o,l=document.getElementById("oc-model-row-"+n),r=document.getElementById("oc-fallback-row-"+n),d=document.getElementById("cursor-model-row-"+n),c=document.getElementById("claudecode-model-row-"+n),p=document.getElementById("codex-model-row-"+n),u=document.getElementById("gemini-model-row-"+n),m=document.getElementById("crew-cli-config-row-"+n),g=document.getElementById("loop-row-"+n);l&&(l.style.display="opencode"===o?"flex":"none"),r&&(r.style.display="opencode"===o?"flex":"none"),d&&(d.style.display="cursor"===o?"flex":"none"),c&&(c.style.display="claude-code"===o||"claudecode"===o?"flex":"none"),p&&(p.style.display="codex"===o?"flex":"none"),u&&(u.style.display="gemini-cli"===o||"gemini"===o?"flex":"none"),m&&(m.style.display="crew-cli"===o?"flex":"none"),g&&(g.style.display=s?"flex":"none");try{await t("/api/agents-config/update",a);const i=f.find(e=>e.id===o)||{label:o};e(`${n} → ${i.label||o}`)}catch(v){e("Failed: "+v.message,!0)}}async function H(n){var o;const a=((null==(o=document.getElementById("cursor-model-txt-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,cursorCliModel:a}),e(n+" Cursor model → "+(a||"auto"))}catch(i){e("Failed: "+i.message,!0)}}async function z(n){var o;const a=((null==(o=document.getElementById("claudecode-model-txt-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,claudeCodeModel:a}),e(n+" Claude Code model → "+(a||"auto"))}catch(i){e("Failed: "+i.message,!0)}}async function D(n){var o;const a=((null==(o=document.getElementById("codex-model-txt-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,codexModel:a}),e(n+" Codex model → "+(a||"auto"))}catch(i){e("Failed: "+i.message,!0)}}async function G(n){var o;const a=((null==(o=document.getElementById("gemini-model-txt-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,geminiCliModel:a}),e(n+" Gemini model → "+(a||"auto"))}catch(i){e("Failed: "+i.message,!0)}}async function q(n){var o;const a=((null==(o=document.getElementById("crew-cli-model-txt-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,useCrewCLI:!0,crewCliModel:a}),e(n+" Crew CLI model → "+(a||"default"))}catch(i){e("Failed: "+i.message,!0)}}async function U(n){var o;const a=((null==(o=document.getElementById("oc-fallback-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,opencodeFallbackModel:a}),e(a?n+" OC fallback → "+a:"OC fallback cleared for "+n)}catch(i){e("Failed: "+i.message,!0)}}async function K(n){var o,a;const i=((null==(o=document.getElementById("oc-modeltext-"+n))?void 0:o.value)||"").trim();try{await t("/api/agents-config/update",{agentId:n,opencodeModel:i});L(n,(null==(a=document.getElementById("modeltext-"+n))?void 0:a.value.trim())||"",i),e(n+" OC model → "+(i||"default"))}catch(s){e("Failed: "+s.message,!0)}}async function V(o,a){const i=["crew-coder","crew-coder-front","crew-coder-back","crew-frontend","crew-fixer","crew-architect","crew-ml","crew-copywriter","crew-main","crew-pm","crew-mega","crew-lead"],s=(await n("/api/engines").catch(()=>({engines:[]}))).engines.find(e=>e.id===o),l=s?s.label:"direct"===o?"Direct API":o;e("Applying "+l+" to all coding agents…");for(const e of i)try{const n={agentId:e,useOpenCode:!1,useCursorCli:!1,useClaudeCode:!1,useCodex:!1,useGeminiCli:!1,useCrewCLI:!1,useDockerSandbox:!1};"opencode"===o?n.useOpenCode=!0:"cursor"===o?n.useCursorCli=!0:"claudecode"===o||"claude-code"===o?n.useClaudeCode=!0:"codex"===o?n.useCodex=!0:"gemini"===o||"gemini-cli"===o?n.useGeminiCli=!0:"crew-cli"===o?n.useCrewCLI=!0:"docker-sandbox"===o&&(n.useDockerSandbox=!0),a&&"cursor"===o&&(n.cursorCliModel=a),a&&"opencode"===o&&(n.opencodeModel=a),a&&"claudecode"===o&&(n.claudeCodeModel=a),a&&"codex"===o&&(n.codexModel=a),a&&"gemini"===o&&(n.geminiCliModel=a),a&&"crew-cli"===o&&(n.crewCliModel=a),await t("/api/agents-config/update",n),await new Promise(e=>setTimeout(e,50))}catch(r){console.error("bulkSetRoute failed for",e,r.message)}e("Done — "+i.length+" agents set to "+l+(a?" ("+a+")":"")),await A()}window.syncCursorModelText=function(e){const t=document.getElementById("cursor-model-sel-"+e),n=document.getElementById("cursor-model-txt-"+e);t&&n&&(n.value=t.value)},window.syncCodexModelText=function(e){const t=document.getElementById("codex-model-sel-"+e),n=document.getElementById("codex-model-txt-"+e);t&&n&&(n.value=t.value)},window.syncGeminiModelText=function(e){const t=document.getElementById("gemini-model-sel-"+e),n=document.getElementById("gemini-model-txt-"+e);t&&n&&(n.value=t.value)},window.syncCrewCliModelText=function(e){const t=document.getElementById("crew-cli-model-sel-"+e),n=document.getElementById("crew-cli-model-txt-"+e);t&&n&&(n.value=t.value)},window.saveAgentLoop=async function(n){var o,a;const i=(null==(o=document.getElementById("loop-toggle-"+n))?void 0:o.checked)??!1,s=null==(a=document.getElementById("loop-rounds-"+n))?void 0:a.value,l=Math.min(20,Math.max(1,parseInt(s||"10",10)));try{await t("/api/agents-config/update",{agentId:n,opencodeLoop:i,opencodeLoopMaxRounds:l}),e(n+" loop "+(i?`ON (${l} rounds max)`:"OFF"))}catch(r){e("Failed: "+r.message,!0)}},window.syncClaudeCodeModelText=function(e){const t=document.getElementById("claudecode-model-sel-"+e),n=document.getElementById("claudecode-model-txt-"+e);t&&n&&(n.value=t.value)},window.syncOcModelText=function(e){const t=document.getElementById("oc-model-"+e),n=document.getElementById("oc-modeltext-"+e);t&&n&&t.value&&(n.value=t.value)};const Y=["🤖","🧠","⚡","🔥","🎯","🛡️","🔧","🐛","🔬","📋","✍️","🐙","🎨","🖥️","📱","🔒","📊","🚀","💡","🌐","⚙️","🦊","🦾","💻","🏗️","🔍","📝","💬","🧪","🎭"];function Q(e){const t=document.getElementById("aemoji-panel-"+e),n=document.getElementById("aemoji-grid-"+e),o=t.classList.contains("open");document.querySelectorAll(".emoji-picker-panel.open").forEach(e=>e.classList.remove("open")),o||(n.hasChildNodes()||(n.innerHTML=Y.map(t=>'<div class="emoji-opt" data-agent="'+e+'" data-emoji="'+t+'" title="'+t+'">'+t+"</div>").join(""),n.addEventListener("click",function(e){const t=e.target.closest(".emoji-opt");t&&function(e,t){const n="__new__"===e,o=n?document.getElementById("naEmoji"):document.getElementById("aemoji-"+e),a=n?document.getElementById("naEmoji-btn"):document.getElementById("aemoji-btn-"+e);o&&(o.value=t);a&&(a.textContent=t);document.getElementById("aemoji-panel-"+e).classList.remove("open")}(t.dataset.agent,t.dataset.emoji)})),t.classList.add("open"))}async function X(n){var o;const a=document.getElementById("aname-"+n).value.trim(),i=document.getElementById("aemoji-"+n).value.trim(),s=null==(o=document.getElementById("atheme-"+n))?void 0:o.value.trim();try{await t("/api/agents-config/update",{agentId:n,name:a,emoji:i,theme:s}),e("Identity saved for "+n)}catch(l){e("Failed: "+l.message,!0)}}async function J(n){const o=document.getElementById("prompt-"+n).value;try{await t("/api/agents-config/update",{agentId:n,systemPrompt:o}),e("Prompt saved for "+n)}catch(a){e("Failed: "+a.message,!0)}}async function Z(){try{e("Starting crew bridge daemons…");const n=await t("/api/crew/start",{});e(n.message||"Crew started")}catch(n){e("Crew start failed: "+n.message,!0)}}document.addEventListener("click",e=>{e.target.closest(".emoji-picker-wrap")||document.querySelectorAll(".emoji-picker-panel.open").forEach(e=>e.classList.remove("open"))}),window.applyAgentPromptPreset=function(e,t){if(!t||!ae[t])return;const n=document.getElementById("prompt-"+e);n&&(n.value=ae[t]);const o=document.getElementById("atheme-"+e);if(o){const e=oe.find(e=>e.value===t);e&&(o.value=e.label.replace(/^[\u{1F000}-\u{1FFFF}\u2600-\u27BF\uFE0F\u20D0-\u20FF\s]+/u,"").trim())}};const ee={coder:["write_file","read_file","mkdir","run_cmd"],writer:["write_file","read_file"],reviewer:["read_file"],security:["read_file","run_cmd"],orchestrator:["read_file","dispatch"],coordinator:["write_file","read_file","run_cmd","dispatch"],devops:["read_file","run_cmd","git"],comms:["telegram","read_file"]};function te(){const e=document.getElementById("naToolPreset").value;if(!e||!ee[e])return;const t=ee[e];document.querySelectorAll(".naToolCheck").forEach(e=>{e.checked=t.includes(e.dataset.tool)})}async function ne(n){const o=[...document.getElementById("tools-"+n).querySelectorAll("input[type=checkbox]:checked")].map(e=>e.dataset.tool);try{await t("/api/agents-config/update",{agentId:n,alsoAllow:o}),e("Tools saved for "+n)}catch(a){e("Failed: "+a.message,!0)}}const oe=[{value:"frontend",label:"🎨 Frontend (HTML/CSS/JS)"},{value:"backend",label:"⚙️ Backend (Node/API/scripts)"},{value:"fullstack",label:"🧱 Full-stack coder"},{value:"ios",label:"📱 iOS / Swift developer"},{value:"android",label:"🤖 Android / Kotlin developer"},{value:"devops",label:"🔧 DevOps / Infrastructure"},{value:"data",label:"📊 Data / Analytics / Python"},{value:"security",label:"🛡️ Security auditor"},{value:"qa",label:"🧪 QA / tester"},{value:"github",label:"🐙 Git & GitHub ops"},{value:"writer",label:"✍️ Content / copywriter"},{value:"design",label:"🖌️ UI/UX designer"},{value:"pm",label:"📋 Product manager / planner"},{value:"aiml",label:"🤖 AI / ML engineer"},{value:"api",label:"🔌 API designer (REST/GraphQL)"},{value:"database",label:"🗄️ Database specialist"},{value:"reactnative",label:"📱 React Native (cross-platform)"},{value:"web3",label:"🌐 Web3 / Blockchain (Solidity)"},{value:"automation",label:"🕷️ Automation / scraping"},{value:"docs",label:"📖 Technical docs writer"},{value:"orchestrator",label:"🧠 Orchestrator / PM loop"},{value:"lead",label:"🦊 Team lead / coordinator"},{value:"main",label:"⚡ Main agent (general)"}];const ae={frontend:"Frontend implementation specialist. Apple/Linear/Vercel-level polish is the baseline.\n\n## Design standard\n- Typography: system font stack or Inter. 16-18px body, 1.5 line-height. Weight hierarchy (400/500/600/700).\n- Spacing: 8px grid. Section padding 48-96px. Let content breathe.\n- Color: muted neutrals + one accent. Dark mode via CSS custom properties. No pure black (#000).\n- Motion: 200-300ms ease-out. Fade + translateY for reveals. Respect prefers-reduced-motion.\n- Layout: mobile-first, CSS Grid + Flexbox, max-width 1200px. Full-bleed hero sections.\n- Components: rounded corners (8-12px), soft layered shadows, no hard borders.\n- Accessibility: semantic HTML, focus-visible, 4.5:1 contrast, aria-labels.\n\n## Research — use these sources\n- @@WEB_FETCH https://developer.apple.com/design/human-interface-guidelines for Apple HIG\n- @@WEB_SEARCH site:uiverse.io [component] for copy-pasteable HTML/CSS examples (7000+ free)\n- @@WEB_SEARCH site:css-tricks.com [technique] for CSS guides\n- @@WEB_SEARCH awwwards [page type] OR onepagelove [page type] for design inspiration\n- @@WEB_FETCH https://developer.mozilla.org/en-US/docs/Web/CSS/[property] for CSS reference\n- @@WEB_SEARCH site:codepen.io [component] vanilla CSS for interactive examples\n\n## Rules\n- ALWAYS read existing files before editing. Match the design system in place.\n- If no design system exists, establish CSS custom properties (--color-*, --space-*, --radius-*).\n- Test mental model: 375px, 768px, 1440px — all three must look intentional.",backend:"Backend specialist. Node.js, APIs, databases, server logic.\n\n## Standards\n- ES modules, async/await, no callbacks. Prefer native Node APIs over dependencies.\n- Every endpoint: input validation, error handling, proper HTTP status codes, structured JSON responses.\n- Database: parameterized queries only (never string interpolation), connection pooling, transactions for multi-step writes.\n- Auth: bcrypt/argon2 for passwords, JWT with short expiry + refresh tokens. Never plaintext.\n- Logging: structured (JSON), include request ID, timestamp, level.\n- Config via env vars, never hardcoded secrets. Validate required env vars at startup.\n- @@WEB_SEARCH for library APIs and docs when using packages you haven't used recently.\n\n## Rules\n- ALWAYS read existing files before editing. Match patterns and naming.\n- Think about failures: what happens when the request fails, DB is down, or input is malformed?",fullstack:"Full-stack coding specialist. Clean, readable code across the entire stack.\n\n## Standards\n- Small functions, clear names, no dead code. Error handling everywhere.\n- ES modules (import/export), async/await. Match existing code patterns.\n- Frontend: semantic HTML, accessible, responsive. Backend: validate inputs, handle errors, proper status codes.\n- @@WEB_SEARCH for API docs and library usage when using unfamiliar packages.\n\n## Rules\n- ALWAYS read existing files before editing — understand what exists.\n- Surgical edits only — change what's asked, nothing else.\n- Trace the happy path and one error path mentally before reporting done.",qa:"QA specialist. Systematic audits backed by evidence from the actual code.\n\n## Process\n1. @@READ_FILE every file you audit — no exceptions\n2. Check against: error handling, input validation, edge cases, security, performance, correctness\n3. Report ONLY issues you can point to in the actual code with real line numbers\n\n## Output format\n### CRITICAL — Line N: [issue] → Fix: [exact code]\n### HIGH — Line N: [issue] → Fix: [exact code]\n### MEDIUM / LOW\n### Summary: X issues. Verdict: PASS / PASS WITH WARNINGS / FAIL\n\n## Rules\n- Do NOT invent line numbers. Only cite what you read.\n- CRITICAL issues = FAIL verdict. No exceptions.\n- You are NOT a coordinator — do NOT use @@DISPATCH.\n- @@WEB_SEARCH best practices or known vulnerability patterns when unsure.",github:"Git and GitHub specialist.\n\n## Before any operation\n- git status, git config user.name, git config user.email\n- For PRs: gh auth status\n\n## Commit standard\n- Conventional commits: feat(scope):, fix(scope):, chore:, docs:, refactor:, test:\n- Subject ≤72 chars. Body explains WHY, not what.\n- Stage specific files — never git add -A unless asked.\n- Never commit: .env, *.pem, *credentials*, API keys.\n\n## Rules\n- Never force-push to main or master.\n- Always git diff --stat before committing.\n- One logical change per commit.",writer:'Content and copywriting specialist.\n\n## Voice\n- Clear, confident, human. Short sentences. Active voice. Cut every word that doesn\'t earn its place.\n- Headlines: benefit-first, specific, no jargon. "Ship 10x faster" beats "Leverage AI-powered solutions."\n- No buzzwords: leverage, synergy, cutting-edge, revolutionary, seamless, robust.\n- No filler: "In today\'s fast-paced world..." — delete it.\n- Numbers > adjectives. "3 agents, 12 seconds" beats "multiple agents, incredibly fast."\n\n## Research — mandatory\n- @@WEB_SEARCH competitors, market positioning, and facts BEFORE writing. Never invent claims.\n- @@WEB_FETCH reference sites for tone/style inspiration.\n\n## Rules\n- ALWAYS @@WRITE_FILE your output — never just show text in chat.\n- Read existing content first to match voice. After draft, cut 30%.',ios:"iOS/Swift specialist. SwiftUI, UIKit, and native Apple platform code.\n\n## Standards\n- SwiftUI for new views unless the project uses UIKit exclusively.\n- Swift naming: camelCase vars, PascalCase types. async/await over completion handlers.\n- Use @MainActor for UI updates. Structured concurrency with TaskGroup when appropriate.\n- Follow MVVM with ObservableObject/Observable. Keep views thin.\n- @@WEB_SEARCH Apple developer docs and WWDC sessions for current APIs.\n\n## Rules\n- ALWAYS read existing Swift files before editing.\n- Handle optionals safely — guard let / if let, never force-unwrap in production.\n- Support Dynamic Type and VoiceOver accessibility.",android:"Android/Kotlin specialist. Jetpack Compose, Android SDK, and modern Android architecture.\n\n## Standards\n- Jetpack Compose for new UI unless the project uses XML layouts.\n- Architecture: MVVM with ViewModel, StateFlow/SharedFlow, Hilt for DI.\n- Coroutines and Flow for async. Structured concurrency with viewModelScope.\n- Follow Material 3 design guidelines.\n- @@WEB_SEARCH Android developer docs for current API patterns and Compose components.\n\n## Rules\n- ALWAYS read existing files before editing. Match architecture patterns.\n- Handle configuration changes properly. Test on multiple screen sizes.",devops:"DevOps and infrastructure specialist. CI/CD, Docker, shell scripts, IaC.\n\n## Standards\n- Idempotent scripts — safe to run multiple times.\n- Dockerfiles: multi-stage builds, non-root user, minimal base images, .dockerignore.\n- CI/CD: fail fast, cache dependencies, pin action versions.\n- IaC: Terraform state management, modular configs, no hardcoded values.\n- @@WEB_SEARCH current best practices for tools and cloud services.\n\n## Rules\n- ALWAYS read existing configs before editing. Never blindly overwrite deployment configs.\n- Secrets in env vars or secret managers, never in source.\n- Write clear inline comments in all scripts and configs.",data:"Data and analytics specialist. Python, SQL, pandas, data pipelines.\n\n## Standards\n- Clean Python with type hints and docstrings. Validate inputs, handle nulls explicitly.\n- pandas/polars for transformation, matplotlib/plotly for visualization.\n- SQL: parameterized queries, CTEs for readability, explain plans for optimization.\n- @@WEB_SEARCH for library APIs, dataset documentation, and statistical methods.\n\n## Rules\n- ALWAYS read existing data files and schemas before writing code.\n- NEVER overwrite raw data. Transform into new files/tables.\n- Reproducibility: set random seeds, log parameters, version datasets.",security:"Security auditor. OWASP-aware, evidence-based.\n\n## Audit checklist\n- Secrets: hardcoded API keys/tokens/passwords, .env in source, secrets in logs or client code\n- Injection: SQL string concat, unescaped user input (XSS), user input in exec/spawn, path traversal\n- Auth: missing auth on protected routes, broken sessions, privilege escalation, CORS misconfiguration\n- Data: plaintext passwords, sensitive data in URLs, missing rate limiting, no input validation\n- @@WEB_SEARCH to verify if a pattern is actually exploitable when unsure\n\n## Rules\n- @@READ_FILE every file before reporting. Never guess.\n- Report only — NEVER modify files.\n- Output: severity + file:line + vulnerability + exact remediation.\n- Overall risk: CRITICAL / HIGH / MODERATE / LOW.",design:"UI/UX design and implementation specialist. You ship premium, production-ready interfaces.\n\n## Design DNA — Apple.com, Linear.app, Vercel.com, Stripe.com level quality.\n- Reduction: remove every element that doesn't serve the user's goal. White space is a feature.\n- Typography: Inter or system stack. Scale 14/16/20/28/40/56px. Weight 400/500/600/700. Line-height 1.5 body, 1.2 display.\n- Color: neutrals (gray-50→950) + one accent. Dark mode first via custom properties. No pure #000.\n- Spacing: 8px grid. Sections 64-96px vertical pad. Cards 24-32px. CSS gap everywhere.\n- Shadows: layered — sm (0 1px 2px), md (0 4px 16px), lg (0 12px 48px). rgba(0,0,0,0.06-0.12).\n- Motion: 200ms ease-out on interactive elements. Fade + translateY(8px) for reveals. Skeleton screens over spinners.\n- Layout: mobile-first (640/768/1024/1280). Max-width 1200px. CSS Grid pages, Flexbox components.\n\n## Research — use these sources\n- @@WEB_FETCH https://developer.apple.com/design/human-interface-guidelines for Apple HIG\n- @@WEB_SEARCH site:uiverse.io [component] for copy-pasteable HTML/CSS examples (7000+ free)\n- @@WEB_SEARCH site:css-tricks.com [technique] for CSS technique guides\n- @@WEB_SEARCH awwwards [page type] OR onepagelove [page type] for design inspiration\n- @@WEB_SEARCH site:codepen.io [component] vanilla CSS for interactive examples\n\n## Rules\n- Accessible: focus-visible, aria-labels, 4.5:1 contrast, semantic HTML.",pm:'Product manager and project planner. Task decomposition and roadmap management.\n\n## Planning principles\n- Every task: independently deliverable. If it can\'t be tested alone, split it.\n- Imperative form: "Create X", "Add Y to Z", "Fix W in file F". Never "Improve" or "Look into."\n- Each task → one agent, one file path, one deliverable.\n- Include acceptance criteria: what does done look like? What should the agent verify?\n- Task size: completable in 1-2 minutes of LLM work. Bigger = split.\n\n## Anti-patterns\n- "Improve the landing page" → too vague. Which section? What\'s wrong?\n- "Set up the backend" → too broad. Which endpoint? What data? What auth?\n- Tasks without file paths → agent won\'t know where to work.\n\n## Rules\n- Flag missing requirements before handoff.\n- @@WEB_SEARCH to research approaches for unfamiliar features.\n- Update ROADMAP.md with [ ] checkboxes.',aiml:'AI/ML engineering specialist. Model training, fine-tuning, eval, and MLOps.\n\n## Standards\n- Reproducibility: set random seeds, log all hyperparameters, version datasets.\n- Data: validate schema before training. Check for nulls, duplicates, class imbalance.\n- Training: early stopping, gradient clipping, learning rate scheduling.\n- Evaluation: never eval on training data. Hold out test set. Report confidence intervals.\n- Code: type hints, docstrings on public APIs, structured logging.\n\n## Research — critical for ML\n- @@WEB_SEARCH for model cards, API docs, library versions before implementation.\n- @@WEB_FETCH HuggingFace docs, paper abstracts, or API references.\n- @@WEB_SEARCH "[library] breaking changes" when using specific versions.\n\n## Rules\n- ALWAYS read existing code before modifying. Pin dependency versions.\n- Never hardcode paths to datasets or models — use env vars or config.',api:"API design specialist. REST and GraphQL APIs.\n\n## Standards\n- OpenAPI/Swagger specs for all new endpoints. Schema-first design.\n- REST: correct HTTP verbs (GET=read, POST=create, PUT=replace, PATCH=update, DELETE=remove).\n- Status codes: 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Unprocessable, 429 Rate Limited, 500 Server Error.\n- Consistent naming: plural nouns for resources (/users, /orders), kebab-case.\n- Pagination: cursor-based for large datasets. Include total count and next/prev links.\n- Versioning: URL prefix (/v1/) or Accept header.\n- @@WEB_SEARCH site:swagger.io/docs [topic] for OpenAPI spec reference.\n- @@WEB_FETCH https://developer.mozilla.org/en-US/docs/Web/HTTP/Status for status codes.\n\n## Rules\n- ALWAYS read existing routes and schemas before adding new ones. Match patterns.\n- Output both the spec and a working implementation stub.",database:"Database specialist. SQL, migrations, indexes, and query optimization.\n\n## Standards\n- Idempotent migrations (safe to re-run). Use IF NOT EXISTS / IF EXISTS guards.\n- Indexes: all foreign keys, frequently queried columns, composite indexes for common WHERE+ORDER BY.\n- Naming: snake_case tables, singular (user not users). FK: target_table_id. Index: idx_table_column.\n- Always explain query plans for optimization changes.\n- @@WEB_SEARCH site:use-the-index-luke.com [topic] for SQL indexing best practices.\n- @@WEB_SEARCH [database engine] documentation [topic] for engine-specific syntax.\n\n## Rules\n- ALWAYS read existing schema before writing migrations.\n- NEVER drop columns or tables without explicit instruction.\n- Transactions for multi-table changes. Rollback strategy for every migration.",reactnative:"React Native specialist. Cross-platform mobile with Expo or bare RN.\n\n## Standards\n- Functional components with hooks. StyleSheet.create for all styles.\n- Navigation: React Navigation with typed routes. Deep linking support.\n- State: Zustand or React Query for server state. Context sparingly.\n- Platform differences: Platform.select, Platform.OS checks, platform-specific files (.ios.tsx/.android.tsx).\n- @@WEB_SEARCH React Native docs and Expo SDK for current APIs.\n\n## Rules\n- ALWAYS read existing components and navigation before editing.\n- Test mental model on both iOS and Android.\n- Handle safe areas, keyboard avoidance, and different screen sizes.",web3:"Web3 and blockchain specialist. Solidity smart contracts and dApp frontends.\n\n## Standards\n- Storage layout: NEVER change variable order in upgradeable contracts.\n- NatSpec comments on all public and external functions.\n- OpenZeppelin for standard patterns (ERC20, ERC721, AccessControl, Ownable).\n- Gas optimization: pack storage vars, use calldata over memory for read-only, avoid loops over unbounded arrays.\n- @@WEB_SEARCH site:docs.openzeppelin.com [pattern] for audited contract implementations.\n- @@WEB_SEARCH EIP-[number] for Ethereum standard specifications.\n\n## Rules\n- ALWAYS read existing contracts before editing.\n- Test all contracts with Hardhat or Foundry before reporting done.\n- Check: reentrancy guards, integer overflow (Solidity 0.8+ safe), access control on state-changing functions.",automation:"Automation and web scraping specialist. Playwright, Puppeteer, Python scrapers.\n\n## Standards\n- Playwright for JS-heavy sites, requests+BeautifulSoup for static HTML.\n- Always check for APIs first (@@WEB_SEARCH) — scraping is the fallback, not the default.\n- Handle: pagination, login flows, dynamic content, CAPTCHAs (flag, don't bypass).\n- Retry logic with exponential backoff for flaky requests.\n- @@WEB_FETCH to read a page before deciding the scraping approach.\n\n## Rules\n- Store raw data before transforming — never lose the source.\n- Respect robots.txt and rate-limit requests (1-2 req/sec default).\n- Output structured data (JSON/CSV) with clear field names.",docs:"Technical documentation writer. API docs, READMEs, developer guides.\n\n## Standards\n- Write for the reader — assume minimal context, include working examples.\n- Structure: Overview → Installation → Quick Start → Usage → API Reference → Examples → Troubleshooting.\n- Code examples must be copy-pasteable and actually work.\n- @@WEB_SEARCH for prior art, best practices, or similar docs for reference.\n- @@WEB_FETCH specific doc pages before paraphrasing or referencing.\n\n## Rules\n- ALWAYS read the code you're documenting before writing.\n- Keep docs in sync with implementation — flag discrepancies.\n- Markdown output unless another format is requested.\n- No fluff paragraphs. Scannable: headers, bullets, code blocks.",orchestrator:"PM loop orchestrator. Roadmap reading, task expansion, specialist routing.\n\n## Standards\n- Break each roadmap item into a single, scoped, actionable task.\n- Include exact file paths and acceptance criteria in every task.\n- Route to the right specialist based on work type.\n- @@WEB_SEARCH to research approaches for unfamiliar features.\n\n## Rules\n- NEVER implement tasks yourself — planning and delegation only.\n- Keep task descriptions under 200 words.\n- Mark items done only after confirmation from the executing agent.",lead:"Team lead and coordinator. Delegation, progress tracking, blocker escalation.\n\n## Rules\n- Assign tasks to the right agent based on their specialty.\n- Track what's in progress and what's blocked.\n- Escalate failures to crew-fixer and report status.\n- Do NOT implement tasks yourself — delegate everything.\n- Communicate clearly: who is doing what, and what's blocked.",main:"Main agent and general-purpose coordinator. Fallback for tasks that don't fit a specialist.\n\n## Rules\n- Triage requests — handle directly or delegate to the right specialist.\n- @@WEB_SEARCH and @@WEB_FETCH for research tasks.\n- Write and edit files directly for general tasks.\n- Keep responses concise and action-oriented.\n- You're the catch-all — if something falls through the cracks, you handle it."},ie={frontend:{id:"crew-coder-front",name:"Frontend Coder",emoji:"🎨"},backend:{id:"crew-coder-back",name:"Backend Coder",emoji:"⚙️"},fullstack:{id:"crew-coder",name:"Full-stack Coder",emoji:"🧱"},ios:{id:"crew-coder-ios",name:"iOS Coder",emoji:"📱"},android:{id:"crew-coder-android",name:"Android Coder",emoji:"🤖"},devops:{id:"crew-devops",name:"DevOps Engineer",emoji:"🔧"},data:{id:"crew-data",name:"Data Engineer",emoji:"📊"},security:{id:"crew-security",name:"Security Auditor",emoji:"🛡️"},qa:{id:"crew-qa",name:"QA Tester",emoji:"🧪"},github:{id:"crew-github",name:"Git Ops",emoji:"🐙"},writer:{id:"crew-copywriter",name:"Copywriter",emoji:"✍️"},design:{id:"crew-design",name:"UI/UX Designer",emoji:"🖌️"},pm:{id:"crew-pm-agent",name:"Product Manager",emoji:"📋"},aiml:{id:"crew-aiml",name:"AI/ML Engineer",emoji:"🤖"},api:{id:"crew-api",name:"API Designer",emoji:"🔌"},database:{id:"crew-database",name:"Database Specialist",emoji:"🗄️"},reactnative:{id:"crew-rn",name:"React Native Dev",emoji:"📱"},web3:{id:"crew-web3",name:"Web3 Engineer",emoji:"🌐"},automation:{id:"crew-automation",name:"Automation Bot",emoji:"🕷️"},docs:{id:"crew-docs",name:"Docs Writer",emoji:"📖"},orchestrator:{id:"crew-orchestrator",name:"Orchestrator",emoji:"🧠"},lead:{id:"crew-lead",name:"Crew Lead",emoji:"🦊"},main:{id:"crew-main",name:"Main Agent",emoji:"⚡"}};function se(){const e=document.getElementById("naPromptPreset").value;if(!e||!ae[e])return;document.getElementById("naPrompt").value=ae[e];const t=ie[e];if(t){const e=document.getElementById("naId"),n=document.getElementById("naName"),o=document.getElementById("naEmoji");e&&!e.value&&(e.value=t.id),n&&!n.value&&(n.value=t.name),o&&!o.value&&(o.value=t.emoji)}const n=document.getElementById("naTheme");if(n){const t=oe.find(t=>t.value===e);t&&(n.value=t.label.replace(/^[\u{1F000}-\u{1FFFF}\u2600-\u27BF\uFE0F\u20D0-\u20FF\s]+/u,"").trim())}}const le=new Set(["groq/openai/gpt-oss-120b","groq/openai/gpt-oss-20b"]),re={"crew-pm":"PLANNER","crew-orchestrator":"PLANNER",orchestrator:"PLANNER","crew-coder":"WORKER","crew-coder-back":"WORKER","crew-coder-front":"WORKER","crew-frontend":"WORKER","crew-fixer":"WORKER","crew-judge":"JUDGE","crew-qa":"ANALYST","crew-security":"ANALYST","crew-lead":"COORDINATOR","crew-main":"COORDINATOR","crew-architect":"COORDINATOR","crew-ml":"ANALYST","crew-mega":"COORDINATOR","crew-researcher":"COORDINATOR","crew-copywriter":"WORKER","crew-github":"WORKER","crew-seo":"COORDINATOR"},de={PLANNER:"background:rgba(139,92,246,0.12);border:1px solid rgba(139,92,246,0.35);color:#a78bfa;",WORKER:"background:rgba(34,197,94,0.10);border:1px solid rgba(34,197,94,0.30);color:var(--green-hi);",JUDGE:"background:rgba(245,158,11,0.10);border:1px solid rgba(245,158,11,0.30);color:var(--yellow);",ANALYST:"background:rgba(239,68,68,0.10);border:1px solid rgba(239,68,68,0.30);color:var(--red-hi);",COORDINATOR:"background:rgba(56,189,248,0.10);border:1px solid rgba(56,189,248,0.30);color:var(--accent);"},ce={PLANNER:["groq/llama-3.3-70b-versatile","cerebras/llama-3.3-70b","groq/llama-3.1-8b-instant","google/gemini-2.0-flash","openai/gpt-4o-mini","xai/grok-3-mini-fast","mistral/mistral-small-latest","deepseek/deepseek-coder","anthropic/claude-haiku-4-5","cerebras/llama-3.1-8b"],WORKER:["anthropic/claude-sonnet-4-20250514","openai/codex-mini-latest","deepseek/deepseek-chat","opencode/gpt-5.2-codex","opencode/big-pickle","mistral/codestral-latest","openai/gpt-4.1","google/models/gemini-2.5-flash","xai/grok-3","anthropic/claude-sonnet-3-5"],JUDGE:["groq/llama-3.3-70b-versatile","cerebras/llama-3.3-70b","deepseek/deepseek-reasoner","openai/o4-mini","xai/grok-3-mini","google/gemini-2.0-flash","groq/llama-3.1-8b-instant","mistral/mistral-small-latest","anthropic/claude-haiku-4-5","deepseek/deepseek-chat"],ANALYST:["anthropic/claude-sonnet-4-20250514","deepseek/deepseek-reasoner","openai/o4-mini","deepseek/deepseek-chat","xai/grok-3","mistral/mistral-large-latest","google/models/gemini-2.5-flash","groq/llama-3.3-70b-versatile","anthropic/claude-haiku-4-5","google/gemini-2.0-flash"],COORDINATOR:["anthropic/claude-sonnet-4-20250514","openai/gpt-4.1","xai/grok-3","google/models/gemini-2.5-flash","deepseek/deepseek-chat","perplexity/sonar-pro","opencode/big-pickle","openai/gpt-4o","groq/llama-3.3-70b-versatile","xai/grok-3-mini"]};function pe(e,t,n=null){const o=document.getElementById(e);o.innerHTML='<option value="">— select a model —</option>';const a=n&&ce[n]?ce[n]:[],i=new Set(a);if(Object.keys(g).length){if(a.length>0){const e=document.createElement("optgroup");e.label=`⭐ RECOMMENDED FOR ${n}`,a.forEach(n=>{const o=le.has(n),a=document.createElement("option");a.value=n,a.textContent="⭐ "+(o?"⚠ BROKEN — ":"")+n,o&&(a.style.color="var(--red-hi)"),n===t&&(a.selected=!0),e.appendChild(a)}),o.appendChild(e)}for(const[e,n]of Object.entries(g)){const s=document.createElement("optgroup");s.label=e.toUpperCase()+(a.length>0?" (All Models)":""),n.forEach(({id:n,name:o})=>{const a=e+"/"+n;if(i.has(a))return;const l=le.has(a),r=document.createElement("option");r.value=a,r.textContent=(l?"⚠ BROKEN — ":"")+(o?o+" ("+n+")":a),l&&(r.style.color="var(--red-hi)"),a===t&&(r.selected=!0),s.appendChild(r)}),o.appendChild(s)}}else{if(a.length>0){const e=document.createElement("optgroup");e.label=`⭐ RECOMMENDED FOR ${n}`,a.forEach(n=>{const o=le.has(n),a=document.createElement("option");a.value=n,a.textContent="⭐ "+(o?"⚠ BROKEN — ":"")+n,o&&(a.style.color="var(--red-hi)"),n===t&&(a.selected=!0),e.appendChild(a)}),o.appendChild(e)}m.forEach(e=>{if(i.has(e))return;const n=le.has(e),a=document.createElement("option");a.value=e,a.textContent=(n?"⚠ BROKEN — ":"")+e,n&&(a.style.color="var(--red-hi)"),e===t&&(a.selected=!0),o.appendChild(a)})}if(t&&!m.includes(t)&&!i.has(t)){const e=document.createElement("option");e.value=t,e.textContent=t+" (custom)",e.selected=!0,o.prepend(e)}}document.getElementById("newAgentBtn").onclick=()=>{document.getElementById("newAgentForm").style.display="block",pe("naModel","");const e=document.getElementById("naPromptPreset");e&&e.options.length<=1&&oe.forEach(t=>{const n=document.createElement("option");n.value=t.value,n.textContent=t.label,e.appendChild(n)});const t=document.getElementById("naToolsGrid");t&&0===t.querySelectorAll(".naToolCheck").length&&(t.innerHTML=E.map(e=>`\n <label style="display:flex; align-items:flex-start; gap:7px; font-size:12px; color:var(--text-2); cursor:pointer; padding:6px 8px; border-radius:5px; border:1px solid var(--border); background:var(--bg-card2);">\n <input type="checkbox" class="naToolCheck" data-tool="${e.id}" style="accent-color:var(--accent); margin-top:2px; flex-shrink:0;" />\n <div>\n <code style="font-size:11px; color:var(--text-1);">${e.id}</code>\n <div style="font-size:10px; color:var(--text-3); margin-top:2px; line-height:1.3;">${e.desc}</div>\n </div>\n </label>\n `).join(""))},document.getElementById("naCancelBtn").onclick=()=>{document.getElementById("newAgentForm").style.display="none"},document.getElementById("naCreateBtn").onclick=async()=>{const n=document.getElementById("naId").value.trim(),o=n&&!n.startsWith("crew-")&&"orchestrator"!==n?`crew-${n}`:n,a=document.getElementById("naModel").value.trim(),i=document.getElementById("naName").value.trim(),s=document.getElementById("naEmoji").value.trim(),l=document.getElementById("naTheme").value.trim(),r=document.getElementById("naPrompt").value.trim(),d=[...document.querySelectorAll(".naToolCheck:checked")].map(e=>e.dataset.tool),c=d.length?d:I(o);if(o&&a)try{await t("/api/agents-config/create",{id:o,model:a,name:i,emoji:s,theme:l,systemPrompt:r,alsoAllow:c}),e(`Agent "${o}" created — restart gateway-bridge to activate it on the RT bus.`),document.getElementById("newAgentForm").style.display="none",["naId","naName","naTheme","naPrompt"].forEach(e=>{document.getElementById(e).value=""}),document.getElementById("naEmoji").value="🔥",document.getElementById("naEmoji-btn").textContent="🔥",document.getElementById("naModel").innerHTML='<option value="">— select a model —</option>',document.getElementById("naPromptPreset").value="",A()}catch(p){e("Failed: "+p.message,!0)}else e("Agent ID and model are required",!0)},document.getElementById("refreshAgentsBtn").onclick=A,document.getElementById("bulkOptimizeBtn").onclick=async()=>{if(!confirm("Apply role-optimized models to all agents?\n\n• Planners → Fast, cheap models\n• Workers → Precision models\n• Judges → Fast reasoning\n• Analysts → Reasoning models\n• Coordinators → Balanced\n\nSee docs/MODEL-ROLE-OPTIMIZATION.md for details."))return;const n={"crew-pm":"groq/llama-3.3-70b-versatile","crew-orchestrator":"groq/llama-3.3-70b-versatile","crew-judge":"groq/llama-3.3-70b-versatile","crew-coder":"google/models/gemini-2.5-flash-lite","crew-coder-front":"google/models/gemini-2.5-flash-lite","crew-coder-back":"google/models/gemini-2.5-flash-lite","crew-fixer":"deepseek/deepseek-reasoner","crew-qa":"deepseek/deepseek-reasoner","crew-security":"deepseek/deepseek-reasoner","crew-main":"google/models/gemini-2.5-flash-lite","crew-lead":"google/models/gemini-2.5-flash-lite","crew-frontend":"google/models/gemini-2.5-flash-lite","crew-copywriter":"groq/llama-3.3-70b-versatile","crew-researcher":"perplexity/sonar-pro","crew-architect":"deepseek/deepseek-reasoner","crew-seo":"groq/llama-3.3-70b-versatile","crew-ml":"deepseek/deepseek-reasoner","crew-github":"groq/llama-3.3-70b-versatile"};e("Applying role-optimized models…");let o=0;for(const[e,i]of Object.entries(n))try{await t("/api/agents-config/update",{agentId:e,model:i}),o++,await new Promise(e=>setTimeout(e,50))}catch(a){console.error(`Failed to update ${e}:`,a.message)}e(`✅ Updated ${o} agents — Restart bridges to activate`),await A()};export{pe as A,Z as a,j as b,D as c,U as d,K as e,G as f,z as g,H as h,p as i,ne as j,J as k,A as l,O as m,X as n,T as o,F as p,B as q,M as r,u as s,R as t,S as u,Q as v,V as w,se as x,te as y,q as z};
@@ -0,0 +1 @@
1
+ import{e}from"./core-utils-CAVnDoe1.js";let t=[],n=null;function o({hideAllViews:e,setNavActive:t}={}){"function"==typeof e&&e();const n=document.getElementById("benchmarksView");n&&n.classList.add("active"),"function"==typeof t&&t("navBenchmarks"),i().then(()=>{const e=document.getElementById("benchmarkSelect");e&&e.value&&r(e.value)})}async function i(){const e=document.getElementById("benchmarkSelect");if(!e)return;const t=e.value;e.innerHTML='<option value="">— Loading… —</option>';try{const n=await fetch("/api/zeroeval/benchmarks"),o=await n.json();if(!Array.isArray(o))throw new Error("Expected array");if(e.innerHTML='<option value="">— Pick benchmark —</option>',o.forEach(t=>{const n="object"==typeof t?t.benchmark_id||t.id:t,o="object"==typeof t&&t.name||n,i=document.createElement("option");i.value=n,i.textContent=o,e.appendChild(i)}),t&&o.some(e=>("object"==typeof e?e.benchmark_id:e)===t))e.value=t;else{const t="swe-bench-verified";o.some(e=>("object"==typeof e?e.benchmark_id:e)===t)&&(e.value=t)}return e.value}catch(n){e.innerHTML='<option value="">— Failed to load —</option>'}}async function a(){await i();const e=document.getElementById("benchmarkSelect");e&&e.value&&r(e.value)}async function r(t){var n,o;const i=document.getElementById("benchmarkTable"),a=document.getElementById("benchmarkMeta");if(i&&a){if(!t)return i.innerHTML="",void(a.style.display="none");i.innerHTML='<div class="meta" style="padding:20px;">Loading…</div>',a.style.display="none";try{const r=await fetch("/api/zeroeval/benchmarks/"+encodeURIComponent(t)),l=await r.json();if(!r.ok)throw new Error(l.error||l.detail||"Failed to load");const s=l.entries||l.models||[],d=l.total_models??(null==(n=l.statistics)?void 0:n.total_models)??s.length,c=(null==(o=l.statistics)?void 0:o.average_score)??(s.length?s.reduce((e,t)=>e+(t.normalized_score??t.benchmark_score??t.score??0),0)/s.length:0),p=l.benchmark_name||l.name||t,m=l.benchmark_description||l.description||"";if(a.innerHTML="<b>"+e(p)+"</b>"+(m?": "+e(m.slice(0,200)):"")+" | "+d+" models, avg "+(100*c).toFixed(1)+"%",a.style.display="block",!s.length)return void(i.innerHTML='<div class="meta" style="padding:20px;">No model scores for this benchmark.</div>');const u=s.slice(0,100).map(t=>{const n=(null!=t.normalized_score?t.normalized_score:null!=t.benchmark_score?t.benchmark_score:t.score)??0,o=(100*n).toFixed(1),i=null!=t.input_cost_per_million?Math.round(100*t.input_cost_per_million)+"¢":"—",a=null!=t.output_cost_per_million?Math.round(100*t.output_cost_per_million)+"¢":"—",r=t.input_cost_per_million??0,l=t.output_cost_per_million??0,s=r+l>0&&n>0?(100*(r+l)/(100*n)).toFixed(1)+"¢/pt":"—";return'<tr><td style="padding:6px 10px;">'+(t.rank||"-")+'</td><td style="padding:6px 10px;">'+e(t.model_name||t.model_id)+'</td><td style="padding:6px 10px;">'+e(t.organization_name||"")+'</td><td style="padding:6px 10px;font-weight:600;">'+o+'%</td><td style="padding:6px 10px;font-size:11px;" title="¢ per 1M input tokens">'+i+'</td><td style="padding:6px 10px;font-size:11px;" title="¢ per 1M output tokens">'+a+'</td><td style="padding:6px 10px;font-size:11px;" title="¢ per score point (1M in+out / score%)">'+s+'</td><td style="padding:6px 10px;font-size:11px;">'+(t.analysis_method||"-").slice(0,40)+"</td></tr>"}).join("");i.innerHTML='<table style="width:100%;border-collapse:collapse;font-size:12px;"><thead><tr style="border-bottom:1px solid var(--border);"><th style="text-align:left;padding:6px 10px;">Rank</th><th style="text-align:left;padding:6px 10px;">Model</th><th style="text-align:left;padding:6px 10px;">Org</th><th style="text-align:left;padding:6px 10px;">Score</th><th style="text-align:left;padding:6px 10px;" title="¢ per 1M input">in ¢</th><th style="text-align:left;padding:6px 10px;" title="¢ per 1M output">out ¢</th><th style="text-align:left;padding:6px 10px;" title="¢ per score point">¢/pt</th><th style="text-align:left;padding:6px 10px;">Method</th></tr></thead><tbody>'+u+"</tbody></table>"}catch(r){i.innerHTML='<div style="color:var(--red);padding:20px;">Error: '+e(r.message)+"</div>"}}}async function l(){const n=document.getElementById("benchmarkTaskSelect");if(n){n.innerHTML='<option value="">— Loading tasks… —</option>';try{const e=await fetch("/api/benchmark-tasks?benchmark=swe-bench-verified&offset=0&length=50"),o=await e.json();if(!e.ok)throw new Error(o.error||"Failed to load tasks");const i=o.rows||[];t=i.map(e=>e.row||e),n.innerHTML='<option value="">— Pick a task —</option>',t.forEach((e,t)=>{const o=e.instance_id||e.id||`task-${t}`,i=e.repo||"",a=document.createElement("option");a.value=t,a.textContent=o+(i?` (${i})`:""),n.appendChild(a)})}catch(o){n.innerHTML='<option value="">— Failed: '+e(o.message)+" —</option>"}}}function s(e){const n=document.getElementById("benchmarkTaskPreview");if(!n)return;if(""===e||null==e||!t[e])return void(n.style.display="none");const o=t[e],i=o.problem_statement||o.description||"(no problem statement)";n.textContent=i.slice(0,800)+(i.length>800?"\n…":""),n.style.display="block"}async function d(){const e=document.getElementById("benchmarkTaskSelect"),o=document.getElementById("benchmarkRunEngine"),i=document.getElementById("benchmarkRunModel"),a=document.getElementById("benchmarkRunOutput"),r=document.getElementById("benchmarkRunStream"),l=document.getElementById("benchmarkRunStatus"),s=document.getElementById("benchmarkRunStop"),d=document.getElementById("benchmarkRunBtn");if(!(e&&o&&a&&r))return;const c=e.value;if(""===c||null==c||!t[c])return void alert('Pick a task first — click "↻ Load Tasks" if the list is empty.');const p=t[c],m=o.value,u=((null==i?void 0:i.value)||"").trim()||void 0;if(n)try{n.abort()}catch{}n=new AbortController,a.style.display="flex",r.textContent="",l.textContent=`Running on ${m}…`,s&&(s.style.display="inline-block"),d&&(d.disabled=!0);try{const e=(await fetch("/api/benchmark-run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({instanceId:p.instance_id||p.id,problemStatement:p.problem_statement||p.description||"",repo:p.repo||"",hints:p.hints_text||"",engine:m,...u?{model:u}:{}}),signal:n.signal})).body.getReader(),t=new TextDecoder;let o="";for(;;){const{done:n,value:i}=await e.read();if(n)break;o+=t.decode(i,{stream:!0});const a=o.split("\n\n");o=a.pop();for(const e of a){const t=e.replace(/^data:\s*/,"");if(t)try{const e=JSON.parse(t);if("chunk"===e.type&&e.text)r.textContent+=e.text,r.scrollTop=r.scrollHeight;else if("done"===e.type){const t=0===e.exitCode||null==e.exitCode;l.textContent=t?"✓ Done":`✗ Exit ${e.exitCode}`,l.style.color=t?"var(--green)":"var(--red)"}else("error"===e.type||e.error)&&(r.textContent+="\n[error] "+(e.error||e.message||JSON.stringify(e)))}catch{}}}}catch(h){"AbortError"!==h.name?(r.textContent+="\n[stream error] "+h.message,l.textContent="✗ Error",l.style.color="var(--red)"):(l.textContent="⏹ Stopped",l.style.color="var(--text-2)")}finally{s&&(s.style.display="none"),d&&(d.disabled=!1),n=null}}function c(){if(n){try{n.abort()}catch{}n=null}}export{r as loadBenchmarkLeaderboard,i as loadBenchmarkOptions,l as loadBenchmarkTasks,a as loadBenchmarks,s as onBenchmarkTaskSelect,d as runBenchmarkTask,o as showBenchmarks,c as stopBenchmarkRun};