crewswarm 0.9.2 → 0.9.3

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 (207) hide show
  1. package/README.md +22 -9
  2. package/apps/dashboard/dist/assets/{chat-core-Cx4sTxDd.js → chat-core-3KirthZA.js} +1 -1
  3. package/apps/dashboard/dist/assets/index-GSWxxEPO.js +2 -0
  4. package/apps/dashboard/dist/assets/{tab-pm-loop-tab-Bfd449B4.js → tab-pm-loop-tab-DiAPTJXu.js} +1 -1
  5. package/apps/dashboard/dist/assets/{tab-projects-tab-DhNWnlzt.js → tab-projects-tab-SFH4E--a.js} +1 -1
  6. package/apps/dashboard/dist/assets/tab-settings-tab-BselH1c0.js +1 -0
  7. package/apps/dashboard/dist/index.html +82 -11
  8. package/apps/vibe/README.md +2 -2
  9. package/apps/vibe/package.json +1 -1
  10. package/apps/vibe/server.mjs +3 -3
  11. package/crew-lead.mjs +34 -4
  12. package/lib/bridges/gateway-ws.mjs +4 -0
  13. package/lib/crew-lead/chat-handler.mjs +34 -0
  14. package/lib/crew-lead/http-server.mjs +55 -14
  15. package/lib/crew-lead/llm-caller.mjs +24 -8
  16. package/lib/crew-lead/prompts.mjs +7 -0
  17. package/lib/crew-lead/wave-dispatcher.mjs +15 -3
  18. package/lib/crew-lead/ws-router.mjs +219 -27
  19. package/lib/engines/engine-registry.mjs +9 -0
  20. package/lib/engines/rt-envelope.mjs +1 -0
  21. package/lib/engines/runners.mjs +5 -2
  22. package/lib/runtime/paths.mjs +12 -8
  23. package/package.json +35 -15
  24. package/scripts/capture-build-flow.mjs +118 -0
  25. package/scripts/coverage-report.mjs +209 -0
  26. package/scripts/coverage-summary.mjs +47 -0
  27. package/scripts/dashboard-validation.mjs +74 -0
  28. package/scripts/dashboard.mjs +560 -70
  29. package/scripts/live-bridge-matrix.mjs +79 -0
  30. package/scripts/live-cli-matrix.mjs +166 -0
  31. package/scripts/live-crewchat-check.mjs +42 -0
  32. package/scripts/live-engine-matrix.mjs +50 -0
  33. package/scripts/live-provider-failover-matrix.mjs +107 -0
  34. package/scripts/live-provider-matrix.mjs +228 -0
  35. package/scripts/restart-all-from-repo.sh +4 -4
  36. package/scripts/smoke-dispatch.mjs +4 -1
  37. package/scripts/test-blast-radius.mjs +204 -0
  38. package/scripts/test-report-summary.mjs +88 -0
  39. package/scripts/test-reporter.mjs +651 -0
  40. package/scripts/test-rerun.mjs +136 -0
  41. package/scripts/tmux-bridge +130 -0
  42. package/apps/dashboard/dist/assets/chat-core-Cx4sTxDd.js.br +0 -0
  43. package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js.br +0 -0
  44. package/apps/dashboard/dist/assets/components-BS9fQjE_.js.br +0 -0
  45. package/apps/dashboard/dist/assets/core-utils-CmOkXgzi.js.br +0 -0
  46. package/apps/dashboard/dist/assets/index-CF0aJRtC.css.br +0 -0
  47. package/apps/dashboard/dist/assets/index-DnClJ1ee.js +0 -2
  48. package/apps/dashboard/dist/assets/index-DnClJ1ee.js.br +0 -0
  49. package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
  50. package/apps/dashboard/dist/assets/setup-wizard-CA0Or47w.js.br +0 -0
  51. package/apps/dashboard/dist/assets/tab-agents-tab-BgpIsjkw.js.br +0 -0
  52. package/apps/dashboard/dist/assets/tab-comms-tab-kguqTIzD.js.br +0 -0
  53. package/apps/dashboard/dist/assets/tab-contacts-tab-DiOyMYth.js.br +0 -0
  54. package/apps/dashboard/dist/assets/tab-engines-tab-BsdZVvU0.js.br +0 -0
  55. package/apps/dashboard/dist/assets/tab-memory-tab-Cu6u13EQ.js.br +0 -0
  56. package/apps/dashboard/dist/assets/tab-models-tab-BLEjmd19.js.br +0 -0
  57. package/apps/dashboard/dist/assets/tab-pm-loop-tab-Bfd449B4.js.br +0 -0
  58. package/apps/dashboard/dist/assets/tab-projects-tab-DhNWnlzt.js.br +0 -0
  59. package/apps/dashboard/dist/assets/tab-prompts-tab-DVkUNaJd.js.br +0 -0
  60. package/apps/dashboard/dist/assets/tab-services-tab-DU_LH3uG.js.br +0 -0
  61. package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js +0 -1
  62. package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js.br +0 -0
  63. package/apps/dashboard/dist/assets/tab-skills-tab-BpY0uZHW.js.br +0 -0
  64. package/apps/dashboard/dist/assets/tab-spending-tab-DEccQHnt.js.br +0 -0
  65. package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BNrd88-r.js.br +0 -0
  66. package/apps/dashboard/dist/assets/tab-swarm-tab-B1AcjL1W.js.br +0 -0
  67. package/apps/dashboard/dist/assets/tab-usage-tab-BIOOnB-Y.js.br +0 -0
  68. package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
  69. package/apps/dashboard/dist/assets/tab-workflows-tab-B-soSy1k.js.br +0 -0
  70. package/apps/dashboard/dist/index.html.br +0 -0
  71. package/apps/dashboard/dist/index.html.gz +0 -0
  72. package/apps/dashboard/index.html +0 -6529
  73. package/apps/dashboard/package.json +0 -15
  74. package/apps/dashboard/src/app.js +0 -2828
  75. package/apps/dashboard/src/app.js.br +0 -0
  76. package/apps/dashboard/src/app.js.gz +0 -0
  77. package/apps/dashboard/src/chat/chat-actions.js +0 -1847
  78. package/apps/dashboard/src/chat/chat-actions.js.br +0 -0
  79. package/apps/dashboard/src/chat/unified-messages.js +0 -327
  80. package/apps/dashboard/src/chat/unified-messages.js.br +0 -0
  81. package/apps/dashboard/src/cli-process.js +0 -208
  82. package/apps/dashboard/src/cli-process.js.br +0 -0
  83. package/apps/dashboard/src/cli-process.js.gz +0 -0
  84. package/apps/dashboard/src/components/active-tasks-panel.js +0 -175
  85. package/apps/dashboard/src/components/active-tasks-panel.js.br +0 -0
  86. package/apps/dashboard/src/core/api.js +0 -18
  87. package/apps/dashboard/src/core/api.js.br +0 -0
  88. package/apps/dashboard/src/core/dom.js +0 -228
  89. package/apps/dashboard/src/core/dom.js.br +0 -0
  90. package/apps/dashboard/src/core/state.js +0 -91
  91. package/apps/dashboard/src/core/state.js.br +0 -0
  92. package/apps/dashboard/src/core/task-manager.js +0 -134
  93. package/apps/dashboard/src/core/task-manager.js.br +0 -0
  94. package/apps/dashboard/src/orchestration-status.js +0 -127
  95. package/apps/dashboard/src/orchestration-status.js.br +0 -0
  96. package/apps/dashboard/src/setup-wizard.js +0 -562
  97. package/apps/dashboard/src/setup-wizard.js.br +0 -0
  98. package/apps/dashboard/src/styles.css +0 -2085
  99. package/apps/dashboard/src/styles.css.br +0 -0
  100. package/apps/dashboard/src/styles.css.gz +0 -0
  101. package/apps/dashboard/src/tabs/agents-tab.js +0 -2237
  102. package/apps/dashboard/src/tabs/agents-tab.js.br +0 -0
  103. package/apps/dashboard/src/tabs/benchmarks-tab.js +0 -229
  104. package/apps/dashboard/src/tabs/benchmarks-tab.js.br +0 -0
  105. package/apps/dashboard/src/tabs/comms-tab.js +0 -955
  106. package/apps/dashboard/src/tabs/comms-tab.js.br +0 -0
  107. package/apps/dashboard/src/tabs/contacts-tab.js +0 -654
  108. package/apps/dashboard/src/tabs/contacts-tab.js.br +0 -0
  109. package/apps/dashboard/src/tabs/engines-tab.js +0 -175
  110. package/apps/dashboard/src/tabs/engines-tab.js.br +0 -0
  111. package/apps/dashboard/src/tabs/memory-tab.js +0 -182
  112. package/apps/dashboard/src/tabs/memory-tab.js.br +0 -0
  113. package/apps/dashboard/src/tabs/models-tab.js +0 -450
  114. package/apps/dashboard/src/tabs/models-tab.js.br +0 -0
  115. package/apps/dashboard/src/tabs/pm-loop-tab.js +0 -185
  116. package/apps/dashboard/src/tabs/pm-loop-tab.js.br +0 -0
  117. package/apps/dashboard/src/tabs/projects-tab.js +0 -663
  118. package/apps/dashboard/src/tabs/projects-tab.js.br +0 -0
  119. package/apps/dashboard/src/tabs/projects-tab.js.gz +0 -0
  120. package/apps/dashboard/src/tabs/prompts-tab.js +0 -160
  121. package/apps/dashboard/src/tabs/prompts-tab.js.br +0 -0
  122. package/apps/dashboard/src/tabs/services-tab.js +0 -202
  123. package/apps/dashboard/src/tabs/services-tab.js.br +0 -0
  124. package/apps/dashboard/src/tabs/settings-tab.js +0 -861
  125. package/apps/dashboard/src/tabs/settings-tab.js.br +0 -0
  126. package/apps/dashboard/src/tabs/skills-tab.js +0 -284
  127. package/apps/dashboard/src/tabs/skills-tab.js.br +0 -0
  128. package/apps/dashboard/src/tabs/spending-tab.js +0 -173
  129. package/apps/dashboard/src/tabs/spending-tab.js.br +0 -0
  130. package/apps/dashboard/src/tabs/swarm-chat-tab.js +0 -660
  131. package/apps/dashboard/src/tabs/swarm-chat-tab.js.br +0 -0
  132. package/apps/dashboard/src/tabs/swarm-tab.js +0 -538
  133. package/apps/dashboard/src/tabs/swarm-tab.js.br +0 -0
  134. package/apps/dashboard/src/tabs/usage-tab.js +0 -390
  135. package/apps/dashboard/src/tabs/usage-tab.js.br +0 -0
  136. package/apps/dashboard/src/tabs/waves-tab.js +0 -238
  137. package/apps/dashboard/src/tabs/waves-tab.js.br +0 -0
  138. package/apps/dashboard/src/tabs/workflows-tab.js +0 -747
  139. package/apps/dashboard/src/tabs/workflows-tab.js.br +0 -0
  140. package/apps/vibe/.crew/agent-memory/pipeline.json +0 -304
  141. package/apps/vibe/.crew/cost.json +0 -17
  142. package/apps/vibe/.crew/json-parse-metrics.jsonl +0 -27
  143. package/apps/vibe/.crew/pipeline-metrics.jsonl +0 -27
  144. package/apps/vibe/.crew/pipeline-runs/pipeline-0f90c392-2425-4ae5-850c-bd9d17b1d690.jsonl +0 -5
  145. package/apps/vibe/.crew/pipeline-runs/pipeline-1c269dd9-a63f-4fba-af81-5cf08048ef06.jsonl +0 -5
  146. package/apps/vibe/.crew/pipeline-runs/pipeline-288a7765-da24-4a22-89bc-1f3cc9b0562c.jsonl +0 -5
  147. package/apps/vibe/.crew/pipeline-runs/pipeline-2c78fd22-a657-4bd1-bc49-0679fb384409.jsonl +0 -5
  148. package/apps/vibe/.crew/pipeline-runs/pipeline-3da23550-22ed-4904-9a0a-8e79c1f3024c.jsonl +0 -5
  149. package/apps/vibe/.crew/pipeline-runs/pipeline-3e6fe08d-3264-404a-8df3-aab7efef10e7.jsonl +0 -5
  150. package/apps/vibe/.crew/pipeline-runs/pipeline-42eec610-57fe-4e09-9e7e-b315038495c2.jsonl +0 -5
  151. package/apps/vibe/.crew/pipeline-runs/pipeline-4438eb4c-ae13-42b1-90e2-b043d8983be8.jsonl +0 -5
  152. package/apps/vibe/.crew/pipeline-runs/pipeline-4740a9f5-86e7-44b6-a394-de433e291727.jsonl +0 -5
  153. package/apps/vibe/.crew/pipeline-runs/pipeline-49e1da6a-957e-48fd-9220-415019e4f8e2.jsonl +0 -5
  154. package/apps/vibe/.crew/pipeline-runs/pipeline-4c9251db-be68-427b-a3fc-a264f2b5778d.jsonl +0 -5
  155. package/apps/vibe/.crew/pipeline-runs/pipeline-6413fa33-a802-4b57-a8c0-a9056ad67842.jsonl +0 -5
  156. package/apps/vibe/.crew/pipeline-runs/pipeline-65e29a57-664d-4196-8109-017e364f182e.jsonl +0 -5
  157. package/apps/vibe/.crew/pipeline-runs/pipeline-6aa04bc5-9593-4b1f-b58d-3bf2978cb602.jsonl +0 -5
  158. package/apps/vibe/.crew/pipeline-runs/pipeline-6e1cba53-9b70-457e-99e0-59199149dd21.jsonl +0 -5
  159. package/apps/vibe/.crew/pipeline-runs/pipeline-749f41cc-4dac-4204-be64-873a6080a0d2.jsonl +0 -5
  160. package/apps/vibe/.crew/pipeline-runs/pipeline-74d68121-e181-4864-bd9a-c3211341dfaf.jsonl +0 -5
  161. package/apps/vibe/.crew/pipeline-runs/pipeline-8509bc24-142d-4e07-b44a-a50bf99d1103.jsonl +0 -5
  162. package/apps/vibe/.crew/pipeline-runs/pipeline-960339c6-07ca-43ce-9900-f6e1702b39b9.jsonl +0 -5
  163. package/apps/vibe/.crew/pipeline-runs/pipeline-9bef2dd2-6122-42e5-b3d9-19f4d80f9e40.jsonl +0 -5
  164. package/apps/vibe/.crew/pipeline-runs/pipeline-9c6480a9-7031-4146-b241-825b9a2d1de1.jsonl +0 -5
  165. package/apps/vibe/.crew/pipeline-runs/pipeline-9fd42426-8492-4157-9d5f-e1537c060489.jsonl +0 -2
  166. package/apps/vibe/.crew/pipeline-runs/pipeline-ad6d40a3-2f5e-46a9-a345-47caaccc51aa.jsonl +0 -5
  167. package/apps/vibe/.crew/pipeline-runs/pipeline-bc606133-8d5b-4535-8d85-f1a29cdaa981.jsonl +0 -5
  168. package/apps/vibe/.crew/pipeline-runs/pipeline-c1418f4e-b773-4ca1-84a3-216acf36e2f2.jsonl +0 -5
  169. package/apps/vibe/.crew/pipeline-runs/pipeline-c1a13ccd-634a-4d01-a4a7-1177b8a752ff.jsonl +0 -5
  170. package/apps/vibe/.crew/pipeline-runs/pipeline-c7d27b42-249e-4bd4-8f26-6aa998110b8a.jsonl +0 -5
  171. package/apps/vibe/.crew/pipeline-runs/pipeline-cca2e9b9-4a34-4d25-a311-5c793fa7e91e.jsonl +0 -5
  172. package/apps/vibe/.crew/sandbox.json +0 -7
  173. package/apps/vibe/.crew/session.json +0 -330
  174. package/apps/vibe/.crew/training-data.jsonl +0 -0
  175. package/apps/vibe/.github/workflows/studio-quality.yml +0 -37
  176. package/apps/vibe/.studio-data/project-messages/chuck-norris.jsonl +0 -18
  177. package/apps/vibe/.studio-data/project-messages/general.jsonl +0 -81
  178. package/apps/vibe/.studio-data/project-messages/studio-local.jsonl +0 -18
  179. package/apps/vibe/ARCHITECTURE.md +0 -3393
  180. package/apps/vibe/QUICK-REFERENCE.md +0 -211
  181. package/apps/vibe/ROADMAP.md +0 -41
  182. package/apps/vibe/STUDIO-SETUP-COMPLETE.md +0 -35
  183. package/apps/vibe/VISUAL-GUIDE.md +0 -378
  184. package/apps/vibe/capture-demo.mjs +0 -160
  185. package/apps/vibe/capture-full-demo.mjs +0 -255
  186. package/apps/vibe/capture-quickstart.mjs +0 -256
  187. package/apps/vibe/capture-vibe-assets.mjs +0 -71
  188. package/apps/vibe/capture-vibe-video.mjs +0 -260
  189. package/apps/vibe/check-buttons.js +0 -41
  190. package/apps/vibe/diagnose.html +0 -106
  191. package/apps/vibe/fix-buttons.js +0 -103
  192. package/apps/vibe/index.html +0 -3404
  193. package/apps/vibe/package-lock.json +0 -920
  194. package/apps/vibe/scripts/studio-pty-host.py +0 -117
  195. package/apps/vibe/src/main.js +0 -2940
  196. package/apps/vibe/src/register-all-languages.js +0 -98
  197. package/apps/vibe/start-studio.sh +0 -11
  198. package/apps/vibe/test/accessibility-tests.js +0 -77
  199. package/apps/vibe/test/browser-performance-audit.mjs +0 -205
  200. package/apps/vibe/test/performance-tests.js +0 -120
  201. package/apps/vibe/test/security-tests.js +0 -213
  202. package/apps/vibe/tests/e2e.local.mjs +0 -54
  203. package/apps/vibe/tests/server.smoke.mjs +0 -106
  204. package/apps/vibe/update_website.mjs +0 -74
  205. package/apps/vibe/vite.config.js +0 -19
  206. package/lib/crew-lead/chat-handler.mjs.bak +0 -1274
  207. package/lib/engines/rt-envelope.mjs.backup-current +0 -870
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  **The only multi-engine AI coding platform.** Switch between Claude Code, Cursor, Gemini, Codex, and OpenCode mid-conversation. Parallel agents. Persistent sessions. No vendor lock-in.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/crewswarm)](https://www.npmjs.com/package/crewswarm)
6
- [![Tests](https://img.shields.io/badge/tests-957%20passed-brightgreen)]()
6
+ [![Release Check](https://img.shields.io/badge/release_check-required-blue)](https://github.com/crewswarm/crewswarm)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
8
  [![Node.js](https://img.shields.io/badge/Node.js-20%2B-green)](https://nodejs.org)
9
9
  [![Website](https://img.shields.io/badge/website-crewswarm.ai-blue)](https://crewswarm.ai)
@@ -37,18 +37,28 @@ npm install -g crewswarm
37
37
  crewswarm
38
38
  ```
39
39
 
40
- That's it. Dashboard opens at `localhost:4319`, Vibe IDE at `localhost:3333`.
40
+ That's the default path for most users. Dashboard opens at `localhost:4319`, Vibe IDE at `localhost:3333`.
41
41
 
42
- ### Or install from source
42
+ ### Contributor setup from source
43
43
 
44
44
  ```bash
45
45
  git clone https://github.com/crewswarm/crewswarm
46
46
  cd crewswarm
47
47
  bash install.sh
48
48
  npm run doctor
49
- npm start
49
+ npm run restart-all
50
50
  ```
51
51
 
52
+ Use source install when you want to work on crewswarm itself or debug local internals.
53
+
54
+ ### Docker for servers and teams
55
+
56
+ ```bash
57
+ curl -fsSL https://raw.githubusercontent.com/crewswarm/crewswarm/main/scripts/install-docker.sh | bash
58
+ ```
59
+
60
+ Use Docker when you want stronger isolation, easier restarts, or a shared server/team box.
61
+
52
62
  ### What does it cost?
53
63
 
54
64
  **$0.** crewswarm is free and open source (MIT). You bring your own API keys — or use CLI OAuth (Claude, Cursor, Gemini login once, no keys needed). Free options: Gemini CLI (1,000 req/day), Groq (free tier), Ollama (fully local).
@@ -65,6 +75,7 @@ npm start
65
75
  | Browser IDE + terminal | Vibe | Desktop | Desktop | Yes | Yes |
66
76
  | 20+ specialist agents | Yes | 1 | 1 | 1 | 1 |
67
77
  | PM Loop (autonomous roadmap) | Yes | No | No | Partial | No |
78
+ | Swarm Chat (@mention dispatch) | Yes | No | No | No | No |
68
79
  | Local-first / no cloud | Yes | Partial | No | No | No |
69
80
  | Open source | Yes | No | No | No | No |
70
81
 
@@ -161,7 +172,8 @@ crewswarm # Start all services
161
172
  crewswarm pm-loop # Run autonomous PM loop
162
173
  npm run doctor # Preflight check
163
174
  npm run restart-all # Restart the stack
164
- npm test # Run 957 tests
175
+ npm test # 2,500+ tests, 100% passing
176
+ npm run test:report # View test results summary
165
177
  crew exec "Build X" # Send task via CLI
166
178
  ```
167
179
 
@@ -170,11 +182,12 @@ crew exec "Build X" # Send task via CLI
170
182
  ## Deployment
171
183
 
172
184
  ```bash
173
- # Docker
174
- docker-compose up -d
185
+ # Most users
186
+ npm install -g crewswarm
187
+ crewswarm
175
188
 
176
- # Or the one-liner
177
- bash <(curl -fsSL https://raw.githubusercontent.com/crewswarm/crewswarm/main/install.sh)
189
+ # Servers / teams
190
+ curl -fsSL https://raw.githubusercontent.com/crewswarm/crewswarm/main/scripts/install-docker.sh | bash
178
191
  ```
179
192
 
180
193
  See [deploy.html](https://crewswarm.ai/deploy.html) for Docker, cloud VM, and production setup.
@@ -1 +1 @@
1
- import{s as e,a as t,g as n}from"./core-utils-CmOkXgzi.js";let o=!1;function a(){var n;const o=t.chatActiveProjectId;if(!o||"general"===o)return void e("Search requires an active project",!0);const a=document.getElementById("searchModal");a&&(a.style.display="flex",null==(n=document.getElementById("searchInput"))||n.focus())}function s(){const e=document.getElementById("searchModal");e&&(e.style.display="none")}async function r(){var o,a,s,r;const l=t.chatActiveProjectId;if(!l||"general"===l)return void e("Search requires an active project",!0);const c=null==(a=null==(o=document.getElementById("searchInput"))?void 0:o.value)?void 0:a.trim();if(!c)return void e("Enter a search query",!0);const d=(null==(s=document.getElementById("searchCaseSensitive"))?void 0:s.checked)||!1,u=(null==(r=document.getElementById("searchSource"))?void 0:r.value)||"",p=document.getElementById("searchResults");if(p){p.innerHTML='<div style="text-align:center;padding:20px;">Searching...</div>';try{let t=`/api/crew-lead/search-project-messages?projectId=${encodeURIComponent(l)}&q=${encodeURIComponent(c)}`;d&&(t+="&caseSensitive=true"),u&&(t+=`&source=${encodeURIComponent(u)}`);const o=await n(t);if(!o.ok)return void(p.innerHTML=`<div style="color:var(--red);padding:20px;">Error: ${i(o.error)}</div>`);if(0===o.results.length)return void(p.innerHTML='<div style="text-align:center;color:var(--text-3);padding:20px;">No results found</div>');const a={dashboard:"💻",cli:"⚡","sub-agent":"👷",agent:"🤖"};let s=`<div style="margin-bottom:12px;font-weight:600;color:var(--text-2);">${o.results.length} results</div>`;for(const e of o.results){const t=a[e.source]||"📝",n=e.agent?` [${e.agent}]`:"",o=new Date(e.ts).toLocaleString();s+=`\n <div style="border:1px solid var(--border);border-radius:6px;padding:12px;margin-bottom:8px;background:var(--bg-card2);">\n <div style="font-size:11px;color:var(--text-3);margin-bottom:6px;">\n ${t} <strong>${e.source}</strong>${n} · ${o}\n </div>\n <div style="font-size:13px;color:var(--text-1);">\n ${i(e.snippet)}\n </div>\n </div>\n `}p.innerHTML=s,e(`Found ${o.results.length} results`)}catch(g){console.error("Search failed:",g),p.innerHTML=`<div style="color:var(--red);padding:20px;">Search failed: ${i(g.message)}</div>`}}}function i(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function l(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b/i.test(t)||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b.*\/[\w.-]+/i.test(t)||(!!/^>\s*[^\n]+[\u00B7\u2022\u22C5\u2027\u30FB‧⋅]\s*\S/u.test(t)||!!/^[─═━\-]{3,}$/.test(t))))}function c(e,t){if("opencode"!==e&&"antigravity"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!l(e)).join("\n"):n}function d(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^YOLO mode is enabled/i.test(t)||(!!/All tool calls will be automatically approved/i.test(t)||(!!/Loaded cached credentials/i.test(t)||(!!/^Using bundled/i.test(t)||(!!/^Authenticated via/i.test(t)||!!/^OpenTelemetry/i.test(t))))))}function u(e,t){if("gemini"!==e&&"gemini-cli"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!d(e)).join("\n"):n}function p(e){return String(e||"").replace(/\r$/,"")}function g(e,t){const n=p(t);return!n.trim()||(!!/rmcp::/i.test(n)||(!!/error decoding response body.*initialized notification/i.test(n)||(!("codex"!==e||!/worker quit with fatal/i.test(n)||!/rmcp|mcp/i.test(n))||!!("codex"===e&&/\/mcp/i.test(n)&&/127\.0\.0\.1:\d+|localhost:\d+/i.test(n)&&/Connection refused|ConnectError|Transport channel closed|tcp connect error/i.test(n)))))}function m(e){return String(e||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")}function h(e){const t=String(e||"");let n=0;return/SecItemCopyMatching|keychain|Keychain/i.test(t)&&(n+=100),/ERROR:\s|^ERROR\s|error:\s|FATAL|fatal|panic/i.test(t)&&(n+=45),/authentication|unauthorized|\b401\b|\b403\b|not logged in/i.test(t)&&(n+=30),/ENOTFOUND|ECONNREFUSED|ECONNRESET|certificate|TLS|SSL/i.test(t)&&(n+=25),/command not found|No such file|ENOENT/i.test(t)&&(n+=20),n}function f(e,t){const n=String(e||"").split("\n"),o=[];for(const r of n){if(g(t,r))continue;const e=m(p(r)).trim();e&&o.push(e)}if(!o.length)return"";let a=o[0],s=h(a);for(const r of o){const e=h(r);e>s&&(s=e,a=r)}return 0===s&&o.length>4?`${o[0]} (${o.length} lines)`:a}function y(e){var t,n;const{postJSON:o,getJSON:a,appendChatBubble:s,showNotification:r,state:i,getChatSessionId:l,getChatActiveProjectId:d,getCrewLeadInfo:h,appendRoadmapCard:y,getLastAppendedAssistantContent:v,setLastAppendedAssistantContent:x,setLastAppendedUserContent:b,setLastSentContent:w}=e,I="crewswarm_passthrough_log";function C(){var e;const t=document.getElementById("chatProjectSelect"),n=String((null==t?void 0:t.value)||"").trim(),o=document.querySelector("#chatProjectTabs [data-project-id].active"),a=String((null==(e=null==o?void 0:o.dataset)?void 0:e.projectId)||"").trim(),s=n&&"undefined"!==n?n:a&&"undefined"!==a?a:d()||i.chatActiveProjectId||"general";i.chatActiveProjectId=s;try{localStorage.setItem("crewswarm_chat_active_project_id",s)}catch{}return s}const E=[{id:"RESET",label:"Clear session history and start fresh",template:""},{id:"STOP",label:"Cancel all running pipelines (agents keep running)",template:""},{id:"KILL",label:"Kill all pipelines + terminate all agent bridges",template:""},{id:"SEARCH_HISTORY",label:"Search long-term chat history by keyword",template:"your search terms"},{id:"DISPATCH",label:"Dispatch task to an agent",template:'{"agent":"crew-coder","task":"Your task here"}'},{id:"PIPELINE",label:"Multi-step pipeline (waves of agents)",template:'[{"wave":1,"agent":"crew-coder","task":"..."},{"wave":2,"agent":"crew-qa","task":"..."}]'},{id:"PROMPT",label:"Append or set agent system prompt",template:'{"agent":"crew-lead","append":"Your new rule here"}'},{id:"SKILL",label:"Run a skill by name",template:'skillName {"param":"value"}'},{id:"SERVICE",label:"Restart/stop a service or agent",template:"restart crew-coder"},{id:"READ_FILE",label:"Read a file and get its contents",template:"/path/to/file"},{id:"RUN_CMD",label:"Run a shell command",template:"ls -la /home/user/CrewSwarm"},{id:"WEB_SEARCH",label:"Search the web (Perplexity)",template:"your search query"},{id:"WEB_FETCH",label:"Fetch a webpage or URL",template:"https://example.com"},{id:"PROJECT",label:"Draft a new project roadmap",template:'{"name":"MyApp","description":"...","outputDir":"/path/to/dir"}'},{id:"BRAIN",label:"Append a fact to brain.md",template:"crew-lead: fact to remember"},{id:"TOOLS",label:"Grant/revoke tools for an agent",template:'{"agent":"crew-qa","allow":["read_file","write_file"]}'},{id:"CREATE_AGENT",label:"Create a dynamic agent",template:'{"id":"crew-ml","role":"coder","description":"ML specialist"}'},{id:"REMOVE_AGENT",label:"Remove a dynamic agent",template:"crew-ml"},{id:"DEFINE_SKILL",label:"Define a new skill (then @@END_SKILL)",template:'skillName\\n{"description":"...","url":"..."}'},{id:"DEFINE_WORKFLOW",label:"Save a workflow for cron",template:'name\\n[{"agent":"crew-copywriter","task":"..."}]'}];let S=0;const T=[];let L=[],k=0;async function $(e=!1){const t=Date.now();if(!e&&L.length&&t-k<3e4)return L;const n=await a("/api/agents-config");return L=(n.agents||[]).filter(e=>e.id&&"crew-lead"!==e.id).sort((e,t)=>e.id.localeCompare(t.id)),k=t,L}async function A(){var e,t;const n=++S,o=()=>n!==S,r=document.getElementById("chatMessages");r&&(r.dataset.historyLoading="true");try{const n=d(),r=n&&"undefined"!==n?n:"general";if(console.log("📚 [LOAD HISTORY] =================="),console.log("📚 [LOAD HISTORY] START - projectId:",n),console.log("📚 [LOAD HISTORY] state.chatActiveProjectId:",i.chatActiveProjectId),console.log("📚 [LOAD HISTORY] URL hash:",window.location.hash),r){console.log("📚 [LOAD HISTORY] Loading unified project messages (all sources)"),console.log("📚 [LOAD HISTORY] ProjectId:",n);try{const t=`/api/crew-lead/project-messages?projectId=${encodeURIComponent(r)}&limit=250`;console.log("📚 [LOAD HISTORY] Fetching:",t);const n=await a(t);if(o())return;console.log("📚 [LOAD HISTORY] Unified response:",{ok:n.ok,messagesCount:(null==(e=n.messages)?void 0:e.length)||0,sources:n.messages?[...new Set(n.messages.map(e=>e.source))]:[]});const i=document.getElementById("chatMessages");if(!i)return void console.error("📚 [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(i.innerHTML="",i.dataset.historyLoaded="false",x(""),b(""),n.messages&&n.messages.length>0){const e={dashboard:"💻",cli:"⚡",agent:"🤖","sub-agent":"👷"};let t=new Map;try{const e=await a("/api/agents-config");t=new Map(((null==e?void 0:e.agents)||[]).map(e=>[e.id,e]))}catch{}if(o())return;const r=n.messages;console.log("📚 [LOAD HISTORY] Appending",r.length,"unified messages (chunked rAF)...");const l=32;if(await new Promise(n=>{let a=0;const i=()=>{var c,d,u,p,g,m,h,f,y,v;if(o())return void n();const w=Math.min(a+l,r.length);for(;a<w;a++){if(o())return void n();const i=r[a],l=i.agent||(null==(c=i.metadata)?void 0:c.agentId)||null,w=l?t.get(l):null,I=(null==(d=i.metadata)?void 0:d.agentEmoji)||(null==w?void 0:w.emoji)||e[i.source]||"📝",C=(null==(u=i.metadata)?void 0:u.agentName)||(null==w?void 0:w.name)||l||null,E=new Date(i.ts).toLocaleTimeString(),S={emoji:I,source:i.source,agent:C,agentName:C,agentId:l,targetAgent:(null==(p=i.metadata)?void 0:p.targetAgent)||(null==(g=i.metadata)?void 0:g.agentId)||null,engine:(null==(m=i.metadata)?void 0:m.engine)||(null==(h=i.metadata)?void 0:h.runtime)||(null==(f=i.metadata)?void 0:f.model)||null,timestamp:E};s("user"===i.role?"user":"assistant",i.content,null,null,null==(y=i.metadata)?void 0:y.model,null==(v=i.metadata)?void 0:v.engine,S),"assistant"===i.role&&x(i.content),"user"===i.role&&b(i.content)}a<r.length?requestAnimationFrame(i):n()};requestAnimationFrame(i)}),o())return;return console.log("📚 [LOAD HISTORY] ✅ Loaded unified view with all sources"),i.dataset.historyLoaded="true",void(i.scrollTop=i.scrollHeight)}return console.log("📚 [LOAD HISTORY] No messages in unified response (might be empty project)"),void(i.dataset.historyLoaded="true")}catch(l){console.error("📚 [LOAD HISTORY] ⚠️ Unified view failed:",l),console.error("📚 [LOAD HISTORY] Error details:",{message:l.message,stack:l.stack});const e=document.getElementById("chatMessages");if(e){const t=document.createElement("div");t.style.cssText="padding:12px;margin:8px;background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);border-radius:8px;color:#ef4444;font-size:13px;",t.innerHTML="⚠️ <strong>crew-lead unavailable</strong> — Cannot load project message history.<br><small>Check that crew-lead is running: <code>node crew-lead.mjs</code></small>",e.appendChild(t)}console.log("📚 [LOAD HISTORY] Falling back to crew-lead-only history...")}}let c="/api/crew-lead/history?sessionId=owner";r&&"general"!==r&&(c+="&projectId="+encodeURIComponent(r)),console.log("📚 [LOAD HISTORY] Fetching crew-lead history:",c);const u=await a(c);if(o())return;if(console.log("📚 [LOAD HISTORY] Response:",{historyCount:(null==(t=u.history)?void 0:t.length)||0}),console.log("📚 [LOAD HISTORY] Response projectId:",u.projectId),u.history&&u.history.length>0){const e=u.history.filter(e=>"user"===e.role);e.length>0&&(console.log("📚 [LOAD HISTORY] First user msg:",e[0].content.slice(0,50)),console.log("📚 [LOAD HISTORY] Last user msg:",e[e.length-1].content.slice(0,50)))}const p=document.getElementById("chatMessages");if(!p)return void console.error("📚 [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(console.log("📚 [LOAD HISTORY] Clearing chatMessages..."),p.innerHTML="",p.dataset.historyLoaded="false",x(""),b(""),u.history&&u.history.length){const e=u.history.slice(-50);console.log("📚 [LOAD HISTORY] Appending",e.length,"messages..."),e.forEach(e=>{o()||(s("user"===e.role?"user":"assistant",e.content),"assistant"===e.role&&x(e.content),"user"===e.role&&b(e.content))}),console.log("📚 [LOAD HISTORY] Appended",e.length,"messages")}else console.log("📚 [LOAD HISTORY] No history found");if(!u.history||0===u.history.length){const e=JSON.parse(localStorage.getItem(I)||"[]"),t=Date.now()-216e5,n=e.filter(e=>e.timestamp&&"number"==typeof e.timestamp&&e.timestamp>t&&e.text&&e.text.trim().length>0);n.length>0&&O(n),n.length!==e.length&&localStorage.setItem(I,JSON.stringify(n))}p.scrollTop=p.scrollHeight,p.dataset.historyLoaded="true"}catch(c){if(o())return;console.warn("Failed to load chat history:",c);const e=document.getElementById("chatMessages");e&&(e.dataset.historyLoaded="true")}finally{r&&(r.dataset.historyLoading="false"),T.splice(0).forEach(e=>{try{e()}catch{}})}}function O(e){const t=document.getElementById("chatMessages");if(!t||!e.length)return;const n={claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"};for(const o of e)if("user"===o.role)s("user",o.text);else{let e=String(o.text||"").split("\n").filter(e=>!g(o.engine,e)).join("\n").trim();e=c(o.engine,e),e=u(o.engine,e);const a=document.createElement("div");a.className="chat-bubble assistant",a.style.cssText="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;font-family:monospace;font-size:12px;color:var(--text-2);";const s=document.createElement("div");s.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const r=o.exitCode??0;s.textContent=(n[o.engine]||o.engine)+" · direct passthrough "+(0===r?"✓":"⚠")+" (exit "+r+")";const i=document.createElement("div");i.textContent=e||o.text,a.appendChild(s),a.appendChild(i),t.appendChild(a)}}let R=null;async function M(){var e,t;const n=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=n.value.trim();if(!r)return;if(R)return R.abort(),R=null,n.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),void n.focus();const c=(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)||"",d=(null==(t=document.getElementById("chatAgentSelector"))?void 0:t.value)||"",u=document.getElementById("chatModeSelector"),p=(null==u?void 0:u.value)||"crew-lead";if(p.startsWith("cli:")){const e=p.replace("cli:","");return void(await B(r,e))}if("crew-lead"!==p)return void(await z(r,p));if(c)return void(await B(r,c));if(d)return void(await z(r,d));const g=await async function(e){const t=String(e||"").match(/^\s*@([a-zA-Z0-9_-]+)\b([\s\S]*)$/);if(!t)return null;const n=t[1];return n&&"crew-lead"!==n&&(await $()).some(e=>e.id===n)?{agentId:n,message:t[2].trim()||e.trim()}:null}(r);if(g)return void(await z(g.message,g.agentId));n.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),s("user",r),b(r),w(r),x("");const m="typing-"+Date.now(),f=document.createElement("div");f.id=m,f.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;";const I=h()||{emoji:"🧠",name:"crew-lead"};f.textContent=I.emoji+" "+I.name+" is thinking...";const E=document.getElementById("chatMessages");E.appendChild(f),E.scrollTop=E.scrollHeight;const S=new AbortController;try{const e=C(),t=e&&i.projectsData[e],n=await o("/api/chat/unified",{mode:"crew-lead",message:r,sessionId:l(),projectId:e||"general",...(null==t?void 0:t.outputDir)?{projectDir:t.outputDir}:{}},S.signal);if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),!1===n.ok&&n.error?(s("assistant","⚠️ "+n.error),x("")):n.reply&&(v()||(s("assistant",n.reply),x(n.reply),E&&(E.scrollTop=E.scrollHeight))),n.dispatched){const e=Array.isArray(n.dispatched)?n.dispatched.map(e=>(null==e?void 0:e.agent)||(null==e?void 0:e.id)).filter(Boolean):[n.dispatched.agent].filter(Boolean),t=document.createElement("div");t.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.length&&(t.textContent="⚡ Dispatched to "+e.join(", "),E.appendChild(t))}n.pendingProject&&y(E,n.pendingProject),E.scrollTop=E.scrollHeight}catch(T){if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),"AbortError"===T.name)s("assistant","⚠️ Message cancelled"),x("");else{let e=T.message||String(T);try{const t=JSON.parse(e);t&&"string"==typeof t.error&&(e=t.error)}catch{}s("assistant","⚠️ Error: "+e),x("")}E.scrollTop=E.scrollHeight}finally{R=null,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),n.focus()}}function D(e,t,n,o){try{const a=JSON.parse(localStorage.getItem(I)||"[]");a.push({role:e,engine:t,text:n,exitCode:o,timestamp:Date.now()}),a.length>200&&a.splice(0,a.length-200),localStorage.setItem(I,JSON.stringify(a))}catch{}}let j=null;async function H(){var e;const t=document.getElementById("passthroughSessionIndicator");if(!t)return;const n=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!n)return void(t.style.display="none");const o=C(),s=o&&i.projectsData[o],r=(null==s?void 0:s.outputDir)||null,c=l()||"owner";try{const e=(await a("/api/passthrough-sessions")).sessions||{},o=r?`${n}:${r}:${c}`:null,i=o&&(e[o]||e[`${n}:${r}`]);t.style.display=i?"inline-block":"none",t.title=i?`Session active for ${(null==s?void 0:s.name)||(null==r?void 0:r.split("/").pop())||"this project"} — click to clear`:""}catch{t.style.display="none"}}async function B(e,t){var n;const o=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=document.querySelector('[data-action="stopPassthrough"]'),d=document.getElementById("passthroughModel");if(j)return j.abort(),j=null,o.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),void o.focus();o.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),s("user",e);const h=document.getElementById("chatMessages"),y=document.createElement("div");y.className="chat-bubble assistant",y.style.cssText="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;font-family:monospace;font-size:12px;color:var(--text-2);";const v=document.createElement("div");v.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const x=C(),b=x&&i.projectsData[x],w=(null==d?void 0:d.value)||"",I=w?` [${w}]`:"";v.textContent=({claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"}[t]||t)+I+" · direct passthrough"+((null==b?void 0:b.outputDir)?" @ "+b.outputDir.split("/").pop():"");const E=document.createElement("div");y.appendChild(v),y.appendChild(E),h.appendChild(y),h.scrollTop=h.scrollHeight;const S=new AbortController,T=function(e){let t="";return{push(n){t+=String(n||"");const o=t.split("\n");t=o.pop()??"";const a=[];for(const t of o){if(g(e,t))continue;const n=m(p(t)).trimEnd();n&&a.push(n)}return a.length?`${a.join("\n")}\n`:""},flush(){const n=t;if(t="",!n)return"";if(g(e,n))return"";const o=m(p(n)).trimEnd();return o?`${o}\n`:""}}}(t);let L="",k=!1;try{const o=(null==b?void 0:b.outputDir)||void 0,a=(null==(n=document.getElementById("passthroughInjectHistory"))?void 0:n.checked)||!1,s={engine:t,message:e};o&&(s.projectDir=o),s.projectId=x||"general",s.sessionId=l(),a&&(s.injectHistory=!0),w&&(s.model=w);const r=await fetch("/api/chat/unified",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({mode:"cli",...s}),signal:S.signal});if(!r.ok)return void(E.textContent=`Error ${r.status}: ${await r.text()}`);const i=r.body.getReader(),d=new TextDecoder;let p="";for(;;){const{done:n,value:o}=await i.read();if(n)break;p+=d.decode(o,{stream:!0});const a=p.split("\n");p=a.pop()||"";for(const s of a)if(s.startsWith("data: "))try{const n=JSON.parse(s.slice(6));if("chunk"===n.type&&n.text){let e=c(t,n.text);e=u(t,e),e&&(k=!0,E.textContent+=e,h.scrollTop=h.scrollHeight)}else if("stderr"===n.type&&n.text){const e=T.push(n.text);if(e){L+=e;let n=c(t,e);n=u(t,n);n&&(!("opencode"===t||"antigravity"===t)||!k)&&(E.textContent+=n,h.scrollTop=h.scrollHeight)}}else if("done"===n.type){const o=T.flush();if(o){L+=o;let e=c(t,o);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(E.textContent+=e,h.scrollTop=h.scrollHeight)}const a=n.exitCode??0,s=0===a;v.textContent+=` ${s?"✓":"⚠"} (exit ${a})`;const r=f(L,t);if(!s&&r&&!E.textContent.includes(r)){const e=document.createElement("div");e.style.cssText="font-size:11px;font-weight:600;color:var(--danger, #f87171);margin-top:8px;white-space:pre-wrap;word-break:break-word;",e.textContent=`↳ ${r}`,y.appendChild(e),h.scrollTop=h.scrollHeight}D("user",t,e,null),D("engine",t,E.textContent,a)}}catch{}}const g=T.flush();if(g){L+=g;let e=c(t,g);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(E.textContent+=e,h.scrollTop=h.scrollHeight)}}catch($){"AbortError"===$.name?(v.textContent+=" ✗ (killed)",E.textContent+=E.textContent?"\n\n[stopped]":"[stopped]"):E.textContent="Error: "+$.message}finally{j=null,r&&(r.style.display="none"),a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),o.focus(),H()}}let P=null,N=[];async function F(e,t){let n;if(e instanceof File)n=e;else{const e=document.getElementById("imageUpload");if(!e.files||!e.files[0])return;n=e.files[0],e.value=""}const a=n.name,r=n.type;(n.size/1024).toFixed(1);const i=r.startsWith("image/"),l="application/pdf"===r,c=r.includes("spreadsheet")||r.includes("excel")||a.match(/\.(xlsx?|csv)$/i),d=r.includes("document")||a.match(/\.(docx?|txt|md)$/i);let u="📎";i?u="📷":l?u="📄":c?u="📊":d&&(u="📝");const p=document.getElementById("chatInput"),g=p?p.value.trim():"",m=t||g||(i?"Describe this image in detail. What do you see?":`Analyze this ${a} file`);s("user",`${u} [Attached: ${a}] ${g?`\n\n${g}`:""}`),s("assistant",`🔍 Analyzing ${i?"image":"file"}...`);try{const e=await function(e){return new Promise((t,n)=>{const o=new FileReader;o.onload=()=>t(o.result),o.onerror=n,o.readAsDataURL(e)})}(n),t=await o("/api/analyze-image",{image:e,prompt:m,fileName:a,fileType:r});t.ok?(s("assistant",`**${i?"Image":"File"} Analysis:**\n\n${t.result}`),p&&(p.value=`[Attached: ${a}]\n\n${t.result}\n\n`,p.focus())):s("assistant",`⚠️ Analysis failed: ${t.error}`)}catch(h){s("assistant",`⚠️ Analysis error: ${h.message}`)}p&&g&&(p.value="")}async function z(e,t){const n=document.getElementById("chatInput");document.querySelector('[data-action="sendChat"]');const r=document.getElementById("chatMessages");n.value="",s("user",e),b(e),w(e);let i={emoji:"🤖",name:t,model:""};try{const e=((await a("/api/agents-config")).agents||[]).find(e=>e.id===t);e&&(i={emoji:e.emoji||"🤖",name:e.name||t,model:U(e)})}catch(u){console.warn("Could not fetch agent info:",u)}const c="typing-"+Date.now(),d=document.createElement("div");d.id=c,d.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;",d.textContent=`${i.emoji} ${i.name} is thinking...`,r.appendChild(d),r.scrollTop=r.scrollHeight;try{const n=C(),a=await o("/api/chat/unified",{mode:"agent",agentId:t,message:e,sessionId:`dashboard-chat-${t}-${l()}`,projectId:n||"general"});if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),a.error)return Y(i,"⚠️ "+a.error,r),void x("");if(a.reply&&(Y(i,a.reply,r),x(a.reply)),a.cliInvoked){const e=document.createElement("div");e.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.textContent=`⚡ Executing ${a.cliInvoked}... (check process status)`,r.appendChild(e)}r.scrollTop=r.scrollHeight}catch(u){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),Y(i,"⚠️ Error: "+u.message,r),x("")}}function Y(e,t,n){const o=document.createElement("div");o.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;";const a=document.createElement("div");if(a.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;align-items:center;gap:6px;",a.textContent=`${e.emoji} ${e.name}`,e.model){const t=document.createElement("span");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;";const[n,...o]=e.model.split("/");t.textContent=o.join("/")||e.model,a.appendChild(t)}const s=document.createElement("div");s.style.cssText="max-width:80%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);white-space:pre-wrap;word-break:break-word;line-height:1.5;border:1px solid var(--border);",s.textContent=t,o.appendChild(a),o.appendChild(s),n.appendChild(o)}function U(e){const{route:t,model:n}=function(e){return e.useCursorCli?{route:"cursor",model:e.cursorCliModel||"auto"}:e.useClaudeCode?{route:"claude",model:e.claudeCodeModel||"auto"}:e.useCodex?{route:"codex",model:e.codexModel||"auto"}:e.useGeminiCli?{route:"gemini",model:e.geminiCliModel||"auto"}:e.useCrewCLI?{route:"crew-cli",model:e.crewCliModel||"auto"}:!0===e.useOpenCode?{route:"opencode",model:e.opencodeModel||e.model||"default"}:{route:"llm",model:e.model||"no model"}}(e);return"llm"===t?n:`${t}:${n}`}[document.getElementById("chatInput"),document.getElementById("chatMessages")].forEach(e=>{e&&(e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="2px dashed var(--accent, #3b82f6)"}),e.addEventListener("dragleave",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline=""}),e.addEventListener("drop",async t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="";const n=t.dataTransfer.files;if(n&&n.length>0){const e=n[0];await F(e)}}))});let q=0;async function _(e=!1){if(!e&&Date.now()-q<5e3)return;const t=document.getElementById("chatModeSelector"),n=document.getElementById("agentsOptgroup");if(t&&n)try{const e=(await a("/api/agents-config")).agents||[],t=new Set(["crew-lead","orchestrator","crew-orchestrator","crew-pm-cli","crew-pm-frontend","crew-pm-core"]);n.innerHTML="",e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const o=e.emoji||"🤖",a=U(e);t.textContent=`${o} ${e.id} — ${a}`,n.appendChild(t)}),q=Date.now()}catch(s){console.error("Failed to load agents for unified mode selector:",s)}const o=document.getElementById("chatAgentSelector");if(o)try{const e=(await a("/api/agents-config")).agents||[];o.innerHTML='<option value="">🧠 Crew Lead (default)</option>';const t=new Set(["crew-lead","orchestrator","crew-orchestrator"]);e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const n=U(e);t.textContent=`${e.id} — ${n}`,o.appendChild(t)})}catch(s){console.error("Failed to load agents for chat selector:",s)}}_(),null==(t=document.getElementById("chatModeSelector"))||t.addEventListener("focus",()=>{_(!0)});let K=null;function J(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const n=Math.floor(t/60);if(n<60)return`${n}m ${t%60}s`;return`${Math.floor(n/60)}h ${n%60}m`}return K&&clearInterval(K),K=setInterval(async()=>{var e;const t=document.getElementById("chatModeSelector"),n=(null==t?void 0:t.value)||"crew-lead";let o=null;if(n.startsWith("cli:")){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}if("crew-lead"!==n&&(o=n),o||(o=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value),!o){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}try{const e=await a(`/api/cli-processes?agent=${o}`);!function(e){const t=document.getElementById("chatCLIProcessStatus");t&&(0!==e.length?(t.style.display="block",t.innerHTML=e.map(e=>{const t=J(e.duration),n=J(e.idleFor);return`\n <div style="border-left:3px solid ${"running"===e.status?"#22c55e":"#f59e0b"};padding:8px 12px;background:var(--bg-card2);border-radius:6px;margin-bottom:8px;">\n <div style="display:flex;justify-content:space-between;margin-bottom:6px;">\n <span style="font-weight:600;font-family:monospace;font-size:13px;">${"running"===e.status?"⚡":"⏸️"} ${e.cli}</span>\n <span style="text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);">${e.status}</span>\n </div>\n <div style="font-size:12px;color:var(--text-2);line-height:1.5;">\n <div>Task: ${(e.task||"unknown").slice(0,80)}</div>\n <div>Duration: ${t} | Idle: ${n} | Lines: ${e.outputLines||0}</div>\n </div>\n </div>\n `}).join("")):t.style.display="none")}(e.processes||[])}catch(s){console.error("Failed to load CLI process status:",s)}},3e3),null==(n=document.getElementById("chatAgentSelector"))||n.addEventListener("change",()=>{var e;const t=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value;t&&r(`Switched to ${t} - messages go directly to this agent's LLM`,"success")}),{loadChatHistory:A,waitForChatHistoryIdle:function(){const e=document.getElementById("chatMessages");return e&&"true"===e.dataset.historyLoading?new Promise(e=>{T.push(e)}):Promise.resolve()},chatAtAtInput:function(){const e=document.getElementById("chatInput"),t=document.getElementById("chatAtAtMenu"),n=document.getElementById("chatAtAtTemplate");if(e&&t&&n)try{const o=e.value,a=e.selectionStart,s=o.slice(0,a),r=s.match(/(^|\s)@([a-zA-Z0-9_-]*)$/);if(r&&s.lastIndexOf("@@")!==s.length-r[0].length)return void $().then(s=>{const i=(r[2]||"").toLowerCase(),l=s.filter(e=>e.id.toLowerCase().includes(i)).slice(0,8);if(!l.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.dataset.mode="mention",t.innerHTML="",l.forEach(s=>{const i=document.createElement("div");i.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",i.onmouseenter=function(){i.style.background="var(--bg-hover)"},i.onmouseleave=function(){i.style.background=""},i.innerHTML=`<span style="color:var(--accent);font-weight:600;">@${s.id}</span> <span style="color:var(--text-3);">${s.name||s.role||"agent"}</span>`,i.onclick=function(){const i=a-r[0].length+r[1].length,l=`@${s.id} `;e.value=o.slice(0,i)+l+o.slice(a),e.selectionStart=e.selectionEnd=i+l.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=`Mention target: @${s.id}`},t.appendChild(i)}),n.style.display="block",n.textContent=i?`Matching agents for @${i}`:"Type an agent name, e.g. @crew-coder"}).catch(()=>{t.style.display="none",n.style.display="none"});const i=s.lastIndexOf("@@");if(-1===i)return t.style.display="none",void(n.style.display="none");const l=s.slice(i+2);if(/\s/.test(l))return t.style.display="none",void(n.style.display="none");const c=l.toUpperCase(),d=E.filter(e=>0===e.id.indexOf(c));if(0===d.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.style.visibility="visible",t.dataset.mode="atat",t.innerHTML="",d.forEach(s=>{const r=document.createElement("div");r.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",r.onmouseenter=function(){r.style.background="var(--bg-hover)"},r.onmouseleave=function(){r.style.background=""},r.innerHTML='<span style="color:var(--accent);font-weight:600;">@@'+s.id+'</span> <span style="color:var(--text-3);">'+s.label+"</span>",r.onclick=function(){const r="@@"+s.id+(s.template?" "+s.template:"");e.value=o.slice(0,i)+r+o.slice(a),e.selectionStart=e.selectionEnd=i+r.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=("PROMPT"===s.id?"Full line to send: @@PROMPT ":"Template: ")+(s.template?s.template:"")},t.appendChild(r)});const u=d.find(e=>e.id===c);u?(n.style.display="block",n.textContent=("PROMPT"===u.id?"Full line: @@PROMPT ":"Template: ")+(u.template||"")):n.style.display="none"}catch(o){"undefined"!=typeof console&&console.warn("chatAtAtInput",o)}},chatKeydown:function(e){const t=document.getElementById("chatAtAtMenu");if(t&&"block"===t.style.display&&("Enter"===e.key||"Tab"===e.key)){const n=t.firstElementChild;if(n)return e.preventDefault(),void n.click()}"Enter"!==e.key||e.shiftKey||(e.preventDefault(),M()),!t||"block"!==t.style.display||"Escape"!==e.key&&"Tab"!==e.key||(t.style.display="none")},sendChat:M,sendDirectAgent:z,loadChatAgentSelector:_,clearChatHistory:async function(){if(!confirm("Clear chat history for this session?"))return;const e=document.getElementById("chatMessages");e.innerHTML="",e.dataset.historyLoaded="false",localStorage.removeItem(I),await o("/api/crew-lead/clear",{sessionId:l()}).catch(()=>{}),await A()},restorePassthroughLog:function(){var e;try{const t=JSON.parse(localStorage.getItem(I)||"[]");if(!t.length)return;const n=document.getElementById("chatMessages");if(!n)return;(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)&&0===n.children.length&&(O(t),n.scrollTop=n.scrollHeight)}catch{}},sendPassthrough:B,stopAll:async function(){if(confirm("Stop all running pipelines?"))try{await o("/api/crew-lead/chat",{message:"@@STOP",sessionId:l()}),r("⏹ Stop signal sent")}catch(e){r("Failed: "+e.message,!0)}},killAll:async function(){if(confirm("Kill all agents? Bridges must be restarted after."))try{await o("/api/crew-lead/chat",{message:"@@KILL",sessionId:l()}),r("☠️ Kill signal sent")}catch(e){r("Failed: "+e.message,!0)}},killPassthrough:function(){j&&(j.abort(),j=null)},refreshSessionIndicator:H,clearPassthroughSession:async function(){var e;const t=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!t)return;const n=C(),o=n&&i.projectsData[n],a=(null==o?void 0:o.outputDir)||null;if(!a)return;const s=`${t}:${a}:${l()||"owner"}`,c=`${t}:${a}`;try{await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(s)}`,{method:"DELETE"}),await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(c)}`,{method:"DELETE"}),r("Session cleared — next message starts fresh"),H()}catch(d){r("Failed: "+d.message,!0)}},resetSendButton:function(){const e=document.querySelector('[data-action="sendChat"]');e&&(e.textContent="Send",e.className="btn-green",e.disabled=!1)},handleImageUpload:F,toggleVoiceRecording:async function(){const e=document.getElementById("recordVoiceBtn");if(P&&"inactive"!==P.state)P.stop(),e.textContent="🎤",e.style.background="";else try{const t=await navigator.mediaDevices.getUserMedia({audio:!0});N=[],P=new MediaRecorder(t,{mimeType:"audio/webm"}),P.ondataavailable=e=>{e.data.size>0&&N.push(e.data)},P.onstop=async()=>{const e=new Blob(N,{type:"audio/webm"});t.getTracks().forEach(e=>e.stop()),s("user",`🎤 [Voice message recorded - ${(e.size/1024).toFixed(0)} KB]`),s("assistant","🎤 Transcribing voice...");try{const t=new FormData;t.append("audio",e,"voice.webm");const o=new AbortController,a=setTimeout(()=>o.abort(),6e4),r=await fetch("/api/transcribe-audio",{method:"POST",body:t,signal:o.signal});let i;clearTimeout(a);try{i=await r.json()}catch(n){return s("assistant",`⚠️ Transcription error: Server returned invalid response (${r.status})`),void(N=[])}if(i.ok&&i.transcription){s("assistant",`**Transcription:**\n\n"${i.transcription}"`);const e=document.getElementById("chatInput");e.value=i.transcription,e.focus()}else s("assistant",`⚠️ Transcription failed: ${i.error||"No result"}`)}catch(o){const e=o.message||String(o);s("assistant",`⚠️ Transcription error: ${e}${"Failed to fetch"===e?" (Is the dashboard running on port 4319? Try: npm run restart-dashboard)":""}`)}N=[]},P.start(),e.textContent="⏹️",e.style.background="var(--red, #ef4444)",r("🎤 Recording... Click again to stop")}catch(t){r("⚠️ Microphone access denied: "+t.message,!0)}}}}"undefined"!=typeof window&&(window.toggleUnifiedView=async function(){o=!o;const a=document.getElementById("unifiedViewToggle");o?(a.style.background="var(--accent)",a.style.color="#fff",a.textContent="📊 Unified ✓",e("Unified view enabled — showing all sources")):(a.style.background="",a.style.color="",a.textContent="📊 Unified View",e("Standard view restored")),await async function(){const a=t.chatActiveProjectId;if(a&&"general"!==a)if(o)try{const t=await n(`/api/crew-lead/project-messages?projectId=${encodeURIComponent(a)}&limit=100`);if(!t.ok)return console.error("Failed to load unified messages:",t.error),void e("Failed to load unified view",!0);const o=document.getElementById("chatMessages");if(!o)return;o.innerHTML="";const s={dashboard:"💻",cli:"⚡","sub-agent":"👷",agent:"🤖"};for(const e of t.messages){const t=document.createElement("div");t.className=`chat-bubble ${e.role}`;const n=s[e.source]||"📝",a=e.agent?` [${e.agent}]`:"",r=new Date(e.ts).toLocaleTimeString();t.innerHTML=`\n <div style="font-size:10px;color:var(--text-3);margin-bottom:4px;">\n ${n} <strong>${e.source}</strong>${a} · ${r}\n </div>\n <div style="white-space:pre-wrap;word-break:break-word;">${i(e.content)}</div>\n `,o.appendChild(t)}o.scrollTop=o.scrollHeight,e(`Loaded ${t.messages.length} messages from all sources`)}catch(s){console.error("Failed to load unified messages:",s),e("Failed to load unified view",!0)}else window.loadChatHistory&&await window.loadChatHistory()}()},window.openSearchModal=a,window.closeSearchModal=s,window.performSearch=r,window.exportMessages=async function(){const n=t.chatActiveProjectId;if(!n||"general"===n)return void e("Export requires an active project",!0);const o=await new Promise(e=>{const t=document.createElement("div");t.style.cssText="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:10001;display:flex;align-items:center;justify-content:center;",t.innerHTML='\n <div style="background:var(--bg-card);border-radius:12px;padding:24px;max-width:400px;">\n <h3 style="margin:0 0 16px 0;">Export Format</h3>\n <div style="display:flex;flex-direction:column;gap:8px;margin-bottom:16px;">\n <button class="export-format-btn btn-ghost" data-format="markdown" style="text-align:left;padding:12px;">\n 📝 Markdown (.md) — Best for reading\n </button>\n <button class="export-format-btn btn-ghost" data-format="json" style="text-align:left;padding:12px;">\n 📋 JSON — Full data with metadata\n </button>\n <button class="export-format-btn btn-ghost" data-format="csv" style="text-align:left;padding:12px;">\n 📊 CSV — Spreadsheet compatible\n </button>\n <button class="export-format-btn btn-ghost" data-format="txt" style="text-align:left;padding:12px;">\n 📄 Plain Text (.txt)\n </button>\n </div>\n <button onclick="this.closest(\'div\').parentElement.remove()" class="btn-ghost" style="width:100%;">Cancel</button>\n </div>\n ',document.body.appendChild(t),t.querySelectorAll(".export-format-btn").forEach(n=>{n.onclick=()=>{e(n.dataset.format),t.remove()}}),t.onclick=n=>{n.target===t&&(e(null),t.remove())}});if(o)try{e("Exporting...");const t=`/api/crew-lead/export-project-messages?projectId=${encodeURIComponent(n)}&format=${o}&includeMetadata=true`,a=document.createElement("a");a.href=t,a.download=`project-${n}.${"markdown"===o?"md":o}`,document.body.appendChild(a),a.click(),document.body.removeChild(a),e(`Exported as ${o.toUpperCase()}`)}catch(a){console.error("Export failed:",a),e("Export failed: "+a.message,!0)}}),"undefined"!=typeof window&&document.addEventListener("keydown",e=>{if((e.metaKey||e.ctrlKey)&&"k"===e.key){const n=t.chatActiveProjectId;n&&"general"!==n&&(e.preventDefault(),a())}if("Escape"===e.key){const e=document.getElementById("searchModal");e&&"none"!==e.style.display&&s()}"Enter"===e.key&&"searchInput"===e.target.id&&(e.preventDefault(),r())});export{y as i};
1
+ import{s as e,a as t,g as n}from"./core-utils-CmOkXgzi.js";let o=!1;function a(){var n;const o=t.chatActiveProjectId;if(!o||"general"===o)return void e("Search requires an active project",!0);const a=document.getElementById("searchModal");a&&(a.style.display="flex",null==(n=document.getElementById("searchInput"))||n.focus())}function s(){const e=document.getElementById("searchModal");e&&(e.style.display="none")}async function r(){var o,a,s,r;const l=t.chatActiveProjectId;if(!l||"general"===l)return void e("Search requires an active project",!0);const c=null==(a=null==(o=document.getElementById("searchInput"))?void 0:o.value)?void 0:a.trim();if(!c)return void e("Enter a search query",!0);const d=(null==(s=document.getElementById("searchCaseSensitive"))?void 0:s.checked)||!1,u=(null==(r=document.getElementById("searchSource"))?void 0:r.value)||"",p=document.getElementById("searchResults");if(p){p.innerHTML='<div style="text-align:center;padding:20px;">Searching...</div>';try{let t=`/api/crew-lead/search-project-messages?projectId=${encodeURIComponent(l)}&q=${encodeURIComponent(c)}`;d&&(t+="&caseSensitive=true"),u&&(t+=`&source=${encodeURIComponent(u)}`);const o=await n(t);if(!o.ok)return void(p.innerHTML=`<div style="color:var(--red);padding:20px;">Error: ${i(o.error)}</div>`);if(0===o.results.length)return void(p.innerHTML='<div style="text-align:center;color:var(--text-3);padding:20px;">No results found</div>');const a={dashboard:"💻",cli:"⚡","sub-agent":"👷",agent:"🤖"};let s=`<div style="margin-bottom:12px;font-weight:600;color:var(--text-2);">${o.results.length} results</div>`;for(const e of o.results){const t=a[e.source]||"📝",n=e.agent?` [${e.agent}]`:"",o=new Date(e.ts).toLocaleString();s+=`\n <div style="border:1px solid var(--border);border-radius:6px;padding:12px;margin-bottom:8px;background:var(--bg-card2);">\n <div style="font-size:11px;color:var(--text-3);margin-bottom:6px;">\n ${t} <strong>${e.source}</strong>${n} · ${o}\n </div>\n <div style="font-size:13px;color:var(--text-1);">\n ${i(e.snippet)}\n </div>\n </div>\n `}p.innerHTML=s,e(`Found ${o.results.length} results`)}catch(g){console.error("Search failed:",g),p.innerHTML=`<div style="color:var(--red);padding:20px;">Search failed: ${i(g.message)}</div>`}}}function i(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function l(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b/i.test(t)||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b.*\/[\w.-]+/i.test(t)||(!!/^>\s*[^\n]+[\u00B7\u2022\u22C5\u2027\u30FB‧⋅]\s*\S/u.test(t)||!!/^[─═━\-]{3,}$/.test(t))))}function c(e,t){if("opencode"!==e&&"antigravity"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!l(e)).join("\n"):n}function d(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^YOLO mode is enabled/i.test(t)||(!!/All tool calls will be automatically approved/i.test(t)||(!!/Loaded cached credentials/i.test(t)||(!!/^Using bundled/i.test(t)||(!!/^Authenticated via/i.test(t)||!!/^OpenTelemetry/i.test(t))))))}function u(e,t){if("gemini"!==e&&"gemini-cli"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!d(e)).join("\n"):n}function p(e){return String(e||"").replace(/\r$/,"")}function g(e,t){const n=p(t);return!n.trim()||(!!/rmcp::/i.test(n)||(!!/error decoding response body.*initialized notification/i.test(n)||(!("codex"!==e||!/worker quit with fatal/i.test(n)||!/rmcp|mcp/i.test(n))||!!("codex"===e&&/\/mcp/i.test(n)&&/127\.0\.0\.1:\d+|localhost:\d+/i.test(n)&&/Connection refused|ConnectError|Transport channel closed|tcp connect error/i.test(n)))))}function m(e){return String(e||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")}function h(e){const t=String(e||"");let n=0;return/SecItemCopyMatching|keychain|Keychain/i.test(t)&&(n+=100),/ERROR:\s|^ERROR\s|error:\s|FATAL|fatal|panic/i.test(t)&&(n+=45),/authentication|unauthorized|\b401\b|\b403\b|not logged in/i.test(t)&&(n+=30),/ENOTFOUND|ECONNREFUSED|ECONNRESET|certificate|TLS|SSL/i.test(t)&&(n+=25),/command not found|No such file|ENOENT/i.test(t)&&(n+=20),n}function f(e,t){const n=String(e||"").split("\n"),o=[];for(const r of n){if(g(t,r))continue;const e=m(p(r)).trim();e&&o.push(e)}if(!o.length)return"";let a=o[0],s=h(a);for(const r of o){const e=h(r);e>s&&(s=e,a=r)}return 0===s&&o.length>4?`${o[0]} (${o.length} lines)`:a}function y(e){var t,n;const{postJSON:o,getJSON:a,appendChatBubble:s,showNotification:r,state:i,getChatSessionId:l,getChatActiveProjectId:d,getCrewLeadInfo:h,appendRoadmapCard:y,getLastAppendedAssistantContent:v,setLastAppendedAssistantContent:x,setLastAppendedUserContent:b,setLastSentContent:w}=e,I="crewswarm_passthrough_log";function E(){var e;const t=document.getElementById("chatProjectSelect"),n=String((null==t?void 0:t.value)||"").trim(),o=document.querySelector("#chatProjectTabs [data-project-id].active"),a=String((null==(e=null==o?void 0:o.dataset)?void 0:e.projectId)||"").trim(),s=n&&"undefined"!==n?n:a&&"undefined"!==a?a:d()||i.chatActiveProjectId||"general";i.chatActiveProjectId=s;try{localStorage.setItem("crewswarm_chat_active_project_id",s)}catch{}return s}const C=[{id:"RESET",label:"Clear session history and start fresh",template:""},{id:"STOP",label:"Cancel all running pipelines (agents keep running)",template:""},{id:"KILL",label:"Kill all pipelines + terminate all agent bridges",template:""},{id:"SEARCH_HISTORY",label:"Search long-term chat history by keyword",template:"your search terms"},{id:"DISPATCH",label:"Dispatch task to an agent",template:'{"agent":"crew-coder","task":"Your task here"}'},{id:"PIPELINE",label:"Multi-step pipeline (waves of agents)",template:'[{"wave":1,"agent":"crew-coder","task":"..."},{"wave":2,"agent":"crew-qa","task":"..."}]'},{id:"PROMPT",label:"Append or set agent system prompt",template:'{"agent":"crew-lead","append":"Your new rule here"}'},{id:"SKILL",label:"Run a skill by name",template:'skillName {"param":"value"}'},{id:"SERVICE",label:"Restart/stop a service or agent",template:"restart crew-coder"},{id:"READ_FILE",label:"Read a file and get its contents",template:"/path/to/file"},{id:"RUN_CMD",label:"Run a shell command",template:"ls -la /home/user/CrewSwarm"},{id:"WEB_SEARCH",label:"Search the web (Perplexity)",template:"your search query"},{id:"WEB_FETCH",label:"Fetch a webpage or URL",template:"https://example.com"},{id:"PROJECT",label:"Draft a new project roadmap",template:'{"name":"MyApp","description":"...","outputDir":"/path/to/dir"}'},{id:"BRAIN",label:"Append a fact to brain.md",template:"crew-lead: fact to remember"},{id:"TOOLS",label:"Grant/revoke tools for an agent",template:'{"agent":"crew-qa","allow":["read_file","write_file"]}'},{id:"CREATE_AGENT",label:"Create a dynamic agent",template:'{"id":"crew-ml","role":"coder","description":"ML specialist"}'},{id:"REMOVE_AGENT",label:"Remove a dynamic agent",template:"crew-ml"},{id:"DEFINE_SKILL",label:"Define a new skill (then @@END_SKILL)",template:'skillName\\n{"description":"...","url":"..."}'},{id:"DEFINE_WORKFLOW",label:"Save a workflow for cron",template:'name\\n[{"agent":"crew-copywriter","task":"..."}]'}];let S=0;const T=[];let L=[],k=0;async function $(e=!1){const t=Date.now();if(!e&&L.length&&t-k<3e4)return L;const n=await a("/api/agents-config");return L=(n.agents||[]).filter(e=>e.id&&"crew-lead"!==e.id).sort((e,t)=>e.id.localeCompare(t.id)),k=t,L}async function A(){var e,t;const n=++S,o=()=>n!==S,r=document.getElementById("chatMessages");r&&(r.dataset.historyLoading="true");try{const n=d(),r=n&&"undefined"!==n?n:"general";if(console.log("📚 [LOAD HISTORY] =================="),console.log("📚 [LOAD HISTORY] START - projectId:",n),console.log("📚 [LOAD HISTORY] state.chatActiveProjectId:",i.chatActiveProjectId),console.log("📚 [LOAD HISTORY] URL hash:",window.location.hash),r){console.log("📚 [LOAD HISTORY] Loading unified project messages (all sources)"),console.log("📚 [LOAD HISTORY] ProjectId:",n);try{const t=`/api/crew-lead/project-messages?projectId=${encodeURIComponent(r)}&limit=250`;console.log("📚 [LOAD HISTORY] Fetching:",t);const n=await a(t);if(o())return;console.log("📚 [LOAD HISTORY] Unified response:",{ok:n.ok,messagesCount:(null==(e=n.messages)?void 0:e.length)||0,sources:n.messages?[...new Set(n.messages.map(e=>e.source))]:[]});const i=document.getElementById("chatMessages");if(!i)return void console.error("📚 [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(i.innerHTML="",i.dataset.historyLoaded="false",x(""),b(""),n.messages&&n.messages.length>0){const e={dashboard:"💻",cli:"⚡",agent:"🤖","sub-agent":"👷"};let t=new Map;try{const e=await a("/api/agents-config");t=new Map(((null==e?void 0:e.agents)||[]).map(e=>[e.id,e]))}catch{}if(o())return;const r=n.messages;console.log("📚 [LOAD HISTORY] Appending",r.length,"unified messages (chunked rAF)...");const l=32;if(await new Promise(n=>{let a=0;const i=()=>{var c,d,u,p,g,m,h,f,y,v;if(o())return void n();const w=Math.min(a+l,r.length);for(;a<w;a++){if(o())return void n();const i=r[a],l=i.agent||(null==(c=i.metadata)?void 0:c.agentId)||null,w=l?t.get(l):null,I=(null==(d=i.metadata)?void 0:d.agentEmoji)||(null==w?void 0:w.emoji)||e[i.source]||"📝",E=(null==(u=i.metadata)?void 0:u.agentName)||(null==w?void 0:w.name)||l||null,C=new Date(i.ts).toLocaleTimeString(),S={emoji:I,source:i.source,agent:E,agentName:E,agentId:l,targetAgent:(null==(p=i.metadata)?void 0:p.targetAgent)||(null==(g=i.metadata)?void 0:g.agentId)||null,engine:(null==(m=i.metadata)?void 0:m.engine)||(null==(h=i.metadata)?void 0:h.runtime)||(null==(f=i.metadata)?void 0:f.model)||null,timestamp:C};s("user"===i.role?"user":"assistant",i.content,null,null,null==(y=i.metadata)?void 0:y.model,null==(v=i.metadata)?void 0:v.engine,S),"assistant"===i.role&&x(i.content),"user"===i.role&&b(i.content)}a<r.length?requestAnimationFrame(i):n()};requestAnimationFrame(i)}),o())return;return console.log("📚 [LOAD HISTORY] ✅ Loaded unified view with all sources"),i.dataset.historyLoaded="true",void(i.scrollTop=i.scrollHeight)}return console.log("📚 [LOAD HISTORY] No messages in unified response (might be empty project)"),void(i.dataset.historyLoaded="true")}catch(l){console.error("📚 [LOAD HISTORY] ⚠️ Unified view failed:",l),console.error("📚 [LOAD HISTORY] Error details:",{message:l.message,stack:l.stack});const e=document.getElementById("chatMessages");if(e){const t=document.createElement("div");t.style.cssText="padding:12px;margin:8px;background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);border-radius:8px;color:#ef4444;font-size:13px;",t.innerHTML="⚠️ <strong>crew-lead unavailable</strong> — Cannot load project message history.<br><small>Check that crew-lead is running: <code>node crew-lead.mjs</code></small>",e.appendChild(t)}console.log("📚 [LOAD HISTORY] Falling back to crew-lead-only history...")}}let c="/api/crew-lead/history?sessionId=owner";r&&"general"!==r&&(c+="&projectId="+encodeURIComponent(r)),console.log("📚 [LOAD HISTORY] Fetching crew-lead history:",c);const u=await a(c);if(o())return;if(console.log("📚 [LOAD HISTORY] Response:",{historyCount:(null==(t=u.history)?void 0:t.length)||0}),console.log("📚 [LOAD HISTORY] Response projectId:",u.projectId),u.history&&u.history.length>0){const e=u.history.filter(e=>"user"===e.role);e.length>0&&(console.log("📚 [LOAD HISTORY] First user msg:",e[0].content.slice(0,50)),console.log("📚 [LOAD HISTORY] Last user msg:",e[e.length-1].content.slice(0,50)))}const p=document.getElementById("chatMessages");if(!p)return void console.error("📚 [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(console.log("📚 [LOAD HISTORY] Clearing chatMessages..."),p.innerHTML="",p.dataset.historyLoaded="false",x(""),b(""),u.history&&u.history.length){const e=u.history.slice(-50);console.log("📚 [LOAD HISTORY] Appending",e.length,"messages..."),e.forEach(e=>{o()||(s("user"===e.role?"user":"assistant",e.content),"assistant"===e.role&&x(e.content),"user"===e.role&&b(e.content))}),console.log("📚 [LOAD HISTORY] Appended",e.length,"messages")}else console.log("📚 [LOAD HISTORY] No history found");if(!u.history||0===u.history.length){const e=JSON.parse(localStorage.getItem(I)||"[]"),t=Date.now()-216e5,n=e.filter(e=>e.timestamp&&"number"==typeof e.timestamp&&e.timestamp>t&&e.text&&e.text.trim().length>0);n.length>0&&O(n),n.length!==e.length&&localStorage.setItem(I,JSON.stringify(n))}p.scrollTop=p.scrollHeight,p.dataset.historyLoaded="true"}catch(c){if(o())return;console.warn("Failed to load chat history:",c);const e=document.getElementById("chatMessages");e&&(e.dataset.historyLoaded="true")}finally{r&&(r.dataset.historyLoading="false"),T.splice(0).forEach(e=>{try{e()}catch{}})}}function O(e){const t=document.getElementById("chatMessages");if(!t||!e.length)return;const n={claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"};for(const o of e)if("user"===o.role)s("user",o.text);else{let e=String(o.text||"").split("\n").filter(e=>!g(o.engine,e)).join("\n").trim();e=c(o.engine,e),e=u(o.engine,e);const a=document.createElement("div");a.className="chat-bubble assistant",a.style.cssText="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;font-family:monospace;font-size:12px;color:var(--text-2);";const s=document.createElement("div");s.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const r=o.exitCode??0;s.textContent=(n[o.engine]||o.engine)+" · direct passthrough "+(0===r?"✓":"⚠")+" (exit "+r+")";const i=document.createElement("div");i.textContent=e||o.text,a.appendChild(s),a.appendChild(i),t.appendChild(a)}}let R=null;async function M(){var e,t;const n=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=n.value.trim();if(!r)return;if(R)return R.abort(),R=null,n.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),void n.focus();const c=(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)||"",d=(null==(t=document.getElementById("chatAgentSelector"))?void 0:t.value)||"",u=document.getElementById("chatModeSelector"),p=(null==u?void 0:u.value)||"crew-lead";if(p.startsWith("cli:")){const e=p.replace("cli:","");return void(await B(r,e))}if("crew-lead"!==p)return void(await z(r,p));if(c)return void(await B(r,c));if(d)return void(await z(r,d));const g=await async function(e){const t=String(e||"").match(/^\s*@([a-zA-Z0-9_-]+)\b([\s\S]*)$/);if(!t)return null;const n=t[1];return n&&"crew-lead"!==n&&(await $()).some(e=>e.id===n)?{agentId:n,message:t[2].trim()||e.trim()}:null}(r);if(g)return void(await z(g.message,g.agentId));n.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),s("user",r),b(r),w(r),x("");const m="typing-"+Date.now(),f=document.createElement("div");f.id=m,f.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;";const I=h()||{emoji:"🧠",name:"crew-lead"};f.textContent=I.emoji+" "+I.name+" is thinking...";const C=document.getElementById("chatMessages");C.appendChild(f),C.scrollTop=C.scrollHeight;const S=new AbortController;try{const e=E(),t=e&&i.projectsData[e],n=await o("/api/chat/unified",{mode:"crew-lead",message:r,sessionId:l(),projectId:e||"general",...(null==t?void 0:t.outputDir)?{projectDir:t.outputDir}:{}},S.signal);if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),!1===n.ok&&n.error?(s("assistant","⚠️ "+n.error),x("")):n.reply&&(v()||(s("assistant",n.reply),x(n.reply),C&&(C.scrollTop=C.scrollHeight))),n.dispatched){const e=Array.isArray(n.dispatched)?n.dispatched.map(e=>(null==e?void 0:e.agent)||(null==e?void 0:e.id)).filter(Boolean):[n.dispatched.agent].filter(Boolean),t=document.createElement("div");t.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.length&&(t.textContent="⚡ Dispatched to "+e.join(", "),C.appendChild(t))}n.pendingProject&&y(C,n.pendingProject),C.scrollTop=C.scrollHeight}catch(T){if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),"AbortError"===T.name)s("assistant","⚠️ Message cancelled"),x("");else{let e=T.message||String(T);try{const t=JSON.parse(e);t&&"string"==typeof t.error&&(e=t.error)}catch{}s("assistant","⚠️ Error: "+e),x("")}C.scrollTop=C.scrollHeight}finally{R=null,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),n.focus()}}function D(e,t,n,o){try{const a=JSON.parse(localStorage.getItem(I)||"[]");a.push({role:e,engine:t,text:n,exitCode:o,timestamp:Date.now()}),a.length>200&&a.splice(0,a.length-200),localStorage.setItem(I,JSON.stringify(a))}catch{}}let j=null;async function H(){var e;const t=document.getElementById("passthroughSessionIndicator");if(!t)return;const n=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!n)return void(t.style.display="none");const o=E(),s=o&&i.projectsData[o],r=(null==s?void 0:s.outputDir)||null,c=l()||"owner";try{const e=(await a("/api/passthrough-sessions")).sessions||{},o=r?`${n}:${r}:${c}`:null,i=o&&(e[o]||e[`${n}:${r}`]);t.style.display=i?"inline-block":"none",t.title=i?`Session active for ${(null==s?void 0:s.name)||(null==r?void 0:r.split("/").pop())||"this project"} — click to clear`:""}catch{t.style.display="none"}}async function B(e,t){var n;const o=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=document.querySelector('[data-action="stopPassthrough"]'),d=document.getElementById("passthroughModel");if(j)return j.abort(),j=null,o.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),void o.focus();o.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),s("user",e);const h=document.getElementById("chatMessages"),y=document.createElement("div");y.className="chat-bubble assistant",y.style.cssText="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;font-family:monospace;font-size:12px;color:var(--text-2);";const v=document.createElement("div");v.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const x=E(),b=x&&i.projectsData[x],w=(null==d?void 0:d.value)||"",I=w?` [${w}]`:"";v.textContent=({claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"}[t]||t)+I+" · direct passthrough"+((null==b?void 0:b.outputDir)?" @ "+b.outputDir.split("/").pop():"");const C=document.createElement("div");y.appendChild(v),y.appendChild(C),h.appendChild(y),h.scrollTop=h.scrollHeight;const S=new AbortController,T=function(e){let t="";return{push(n){t+=String(n||"");const o=t.split("\n");t=o.pop()??"";const a=[];for(const t of o){if(g(e,t))continue;const n=m(p(t)).trimEnd();n&&a.push(n)}return a.length?`${a.join("\n")}\n`:""},flush(){const n=t;if(t="",!n)return"";if(g(e,n))return"";const o=m(p(n)).trimEnd();return o?`${o}\n`:""}}}(t);let L="",k=!1;try{const o=(null==b?void 0:b.outputDir)||void 0,a=(null==(n=document.getElementById("passthroughInjectHistory"))?void 0:n.checked)||!1,s={engine:t,message:e};o&&(s.projectDir=o),s.projectId=x||"general",s.sessionId=l(),a&&(s.injectHistory=!0),w&&(s.model=w);const r=await fetch("/api/chat/unified",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({mode:"cli",...s}),signal:S.signal});if(!r.ok)return void(C.textContent=`Error ${r.status}: ${await r.text()}`);const i=r.body.getReader(),d=new TextDecoder;let p="";for(;;){const{done:n,value:o}=await i.read();if(n)break;p+=d.decode(o,{stream:!0});const a=p.split("\n");p=a.pop()||"";for(const s of a)if(s.startsWith("data: "))try{const n=JSON.parse(s.slice(6));if("chunk"===n.type&&n.text){let e=c(t,n.text);e=u(t,e),e&&(k=!0,C.textContent+=e,h.scrollTop=h.scrollHeight)}else if("stderr"===n.type&&n.text){const e=T.push(n.text);if(e){L+=e;let n=c(t,e);n=u(t,n);n&&(!("opencode"===t||"antigravity"===t)||!k)&&(C.textContent+=n,h.scrollTop=h.scrollHeight)}}else if("done"===n.type){const o=T.flush();if(o){L+=o;let e=c(t,o);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(C.textContent+=e,h.scrollTop=h.scrollHeight)}const a=n.exitCode??0,s=0===a;v.textContent+=` ${s?"✓":"⚠"} (exit ${a})`;const r=f(L,t);if(!s&&r&&!C.textContent.includes(r)){const e=document.createElement("div");e.style.cssText="font-size:11px;font-weight:600;color:var(--danger, #f87171);margin-top:8px;white-space:pre-wrap;word-break:break-word;",e.textContent=`↳ ${r}`,y.appendChild(e),h.scrollTop=h.scrollHeight}D("user",t,e,null),D("engine",t,C.textContent,a)}}catch{}}const g=T.flush();if(g){L+=g;let e=c(t,g);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(C.textContent+=e,h.scrollTop=h.scrollHeight)}}catch($){"AbortError"===$.name?(v.textContent+=" ✗ (killed)",C.textContent+=C.textContent?"\n\n[stopped]":"[stopped]"):C.textContent="Error: "+$.message}finally{j=null,r&&(r.style.display="none"),a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),o.focus(),H()}}let P=null,N=[];async function F(e,t){let n;if(e instanceof File)n=e;else{const e=document.getElementById("imageUpload");if(!e.files||!e.files[0])return;n=e.files[0],e.value=""}const a=n.name,r=n.type;(n.size/1024).toFixed(1);const i=r.startsWith("image/"),l="application/pdf"===r,c=r.includes("spreadsheet")||r.includes("excel")||a.match(/\.(xlsx?|csv)$/i),d=r.includes("document")||a.match(/\.(docx?|txt|md)$/i);let u="📎";i?u="📷":l?u="📄":c?u="📊":d&&(u="📝");const p=document.getElementById("chatInput"),g=p?p.value.trim():"",m=t||g||(i?"Describe this image in detail. What do you see?":`Analyze this ${a} file`);s("user",`${u} [Attached: ${a}] ${g?`\n\n${g}`:""}`),s("assistant",`🔍 Analyzing ${i?"image":"file"}...`);try{const e=await function(e){return new Promise((t,n)=>{const o=new FileReader;o.onload=()=>t(o.result),o.onerror=n,o.readAsDataURL(e)})}(n),t=await o("/api/analyze-image",{image:e,prompt:m,fileName:a,fileType:r});t.ok?(s("assistant",`**${i?"Image":"File"} Analysis:**\n\n${t.result}`),p&&(p.value=`[Attached: ${a}]\n\n${t.result}\n\n`,p.focus())):s("assistant",`⚠️ Analysis failed: ${t.error}`)}catch(h){s("assistant",`⚠️ Analysis error: ${h.message}`)}p&&g&&(p.value="")}async function z(e,t){const n=document.getElementById("chatInput");document.querySelector('[data-action="sendChat"]');const r=document.getElementById("chatMessages");n.value="",s("user",e),b(e),w(e);let i={emoji:"🤖",name:t,model:""};try{const e=((await a("/api/agents-config")).agents||[]).find(e=>e.id===t);e&&(i={emoji:e.emoji||"🤖",name:e.name||t,model:U(e)})}catch(u){console.warn("Could not fetch agent info:",u)}const c="typing-"+Date.now(),d=document.createElement("div");d.id=c,d.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;",d.textContent=`${i.emoji} ${i.name} is thinking...`,r.appendChild(d),r.scrollTop=r.scrollHeight;try{const n=E(),a=await o("/api/chat/unified",{mode:"agent",agentId:t,message:e,sessionId:`dashboard-chat-${t}-${l()}`,projectId:n||"general"});if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),a.error)return Y(i,"⚠️ "+a.error,r),void x("");if(a.reply&&(Y(i,a.reply,r),x(a.reply)),a.cliInvoked){const e=document.createElement("div");e.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.textContent=`⚡ Executing ${a.cliInvoked}... (check process status)`,r.appendChild(e)}r.scrollTop=r.scrollHeight}catch(u){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),Y(i,"⚠️ Error: "+u.message,r),x("")}}function Y(e,t,n){const o=document.createElement("div");o.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;";const a=document.createElement("div");if(a.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;align-items:center;gap:6px;",a.textContent=`${e.emoji} ${e.name}`,e.model){const t=document.createElement("span");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;";const[n,...o]=e.model.split("/");t.textContent=o.join("/")||e.model,a.appendChild(t)}const s=document.createElement("div");s.style.cssText="max-width:80%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);white-space:pre-wrap;word-break:break-word;line-height:1.5;border:1px solid var(--border);",s.textContent=t,o.appendChild(a),o.appendChild(s),n.appendChild(o)}function U(e){const{model:t,cliEngine:n}=function(e){const t=e.useCursorCli?{route:"cursor",model:e.cursorCliModel||"auto"}:e.useClaudeCode?{route:"claude",model:e.claudeCodeModel||"auto"}:e.useCodex?{route:"codex",model:e.codexModel||"auto"}:e.useGeminiCli?{route:"gemini",model:e.geminiCliModel||"auto"}:e.useCrewCLI?{route:"crew-cli",model:e.crewCliModel||"auto"}:!0===e.useOpenCode?{route:"opencode",model:e.opencodeModel||e.model||"default"}:null;return{route:"llm",model:e.model||"no model",cliEngine:t}}(e);return n?`${t} (code: ${n.route})`:t}[document.getElementById("chatInput"),document.getElementById("chatMessages")].forEach(e=>{e&&(e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="2px dashed var(--accent, #3b82f6)"}),e.addEventListener("dragleave",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline=""}),e.addEventListener("drop",async t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="";const n=t.dataTransfer.files;if(n&&n.length>0){const e=n[0];await F(e)}}))});let q=0;async function _(e=!1){if(!e&&Date.now()-q<5e3)return;const t=document.getElementById("chatModeSelector"),n=document.getElementById("agentsOptgroup");if(t&&n)try{const e=(await a("/api/agents-config")).agents||[],t=new Set(["crew-lead","orchestrator","crew-orchestrator","crew-pm-cli","crew-pm-frontend","crew-pm-core"]);n.innerHTML="",e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const o=e.emoji||"🤖",a=U(e);t.textContent=`${o} ${e.id} — ${a}`,n.appendChild(t)}),q=Date.now()}catch(s){console.error("Failed to load agents for unified mode selector:",s)}const o=document.getElementById("chatAgentSelector");if(o)try{const e=(await a("/api/agents-config")).agents||[];o.innerHTML='<option value="">🧠 Crew Lead (default)</option>';const t=new Set(["crew-lead","orchestrator","crew-orchestrator"]);e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const n=U(e);t.textContent=`${e.id} — ${n}`,o.appendChild(t)})}catch(s){console.error("Failed to load agents for chat selector:",s)}}_(),null==(t=document.getElementById("chatModeSelector"))||t.addEventListener("focus",()=>{_(!0)});let K=null;function J(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const n=Math.floor(t/60);if(n<60)return`${n}m ${t%60}s`;return`${Math.floor(n/60)}h ${n%60}m`}return K&&clearInterval(K),K=setInterval(async()=>{var e;const t=document.getElementById("chatModeSelector"),n=(null==t?void 0:t.value)||"crew-lead";let o=null;if(n.startsWith("cli:")){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}if("crew-lead"!==n&&(o=n),o||(o=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value),!o){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}try{const e=await a(`/api/cli-processes?agent=${o}`);!function(e){const t=document.getElementById("chatCLIProcessStatus");t&&(0!==e.length?(t.style.display="block",t.innerHTML=e.map(e=>{const t=J(e.duration),n=J(e.idleFor);return`\n <div style="border-left:3px solid ${"running"===e.status?"#22c55e":"#f59e0b"};padding:8px 12px;background:var(--bg-card2);border-radius:6px;margin-bottom:8px;">\n <div style="display:flex;justify-content:space-between;margin-bottom:6px;">\n <span style="font-weight:600;font-family:monospace;font-size:13px;">${"running"===e.status?"⚡":"⏸️"} ${e.cli}</span>\n <span style="text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);">${e.status}</span>\n </div>\n <div style="font-size:12px;color:var(--text-2);line-height:1.5;">\n <div>Task: ${(e.task||"unknown").slice(0,80)}</div>\n <div>Duration: ${t} | Idle: ${n} | Lines: ${e.outputLines||0}</div>\n </div>\n </div>\n `}).join("")):t.style.display="none")}(e.processes||[])}catch(s){console.error("Failed to load CLI process status:",s)}},3e3),null==(n=document.getElementById("chatAgentSelector"))||n.addEventListener("change",()=>{var e;const t=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value;t&&r(`Switched to ${t} - messages go directly to this agent's LLM`,"success")}),{loadChatHistory:A,waitForChatHistoryIdle:function(){const e=document.getElementById("chatMessages");return e&&"true"===e.dataset.historyLoading?new Promise(e=>{T.push(e)}):Promise.resolve()},chatAtAtInput:function(){const e=document.getElementById("chatInput"),t=document.getElementById("chatAtAtMenu"),n=document.getElementById("chatAtAtTemplate");if(e&&t&&n)try{const o=e.value,a=e.selectionStart,s=o.slice(0,a),r=s.match(/(^|\s)@([a-zA-Z0-9_-]*)$/);if(r&&s.lastIndexOf("@@")!==s.length-r[0].length)return void $().then(s=>{const i=(r[2]||"").toLowerCase(),l=s.filter(e=>e.id.toLowerCase().includes(i)).slice(0,8);if(!l.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.dataset.mode="mention",t.innerHTML="",l.forEach(s=>{const i=document.createElement("div");i.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",i.onmouseenter=function(){i.style.background="var(--bg-hover)"},i.onmouseleave=function(){i.style.background=""},i.innerHTML=`<span style="color:var(--accent);font-weight:600;">@${s.id}</span> <span style="color:var(--text-3);">${s.name||s.role||"agent"}</span>`,i.onclick=function(){const i=a-r[0].length+r[1].length,l=`@${s.id} `;e.value=o.slice(0,i)+l+o.slice(a),e.selectionStart=e.selectionEnd=i+l.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=`Mention target: @${s.id}`},t.appendChild(i)}),n.style.display="block",n.textContent=i?`Matching agents for @${i}`:"Type an agent name, e.g. @crew-coder"}).catch(()=>{t.style.display="none",n.style.display="none"});const i=s.lastIndexOf("@@");if(-1===i)return t.style.display="none",void(n.style.display="none");const l=s.slice(i+2);if(/\s/.test(l))return t.style.display="none",void(n.style.display="none");const c=l.toUpperCase(),d=C.filter(e=>0===e.id.indexOf(c));if(0===d.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.style.visibility="visible",t.dataset.mode="atat",t.innerHTML="",d.forEach(s=>{const r=document.createElement("div");r.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",r.onmouseenter=function(){r.style.background="var(--bg-hover)"},r.onmouseleave=function(){r.style.background=""},r.innerHTML='<span style="color:var(--accent);font-weight:600;">@@'+s.id+'</span> <span style="color:var(--text-3);">'+s.label+"</span>",r.onclick=function(){const r="@@"+s.id+(s.template?" "+s.template:"");e.value=o.slice(0,i)+r+o.slice(a),e.selectionStart=e.selectionEnd=i+r.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=("PROMPT"===s.id?"Full line to send: @@PROMPT ":"Template: ")+(s.template?s.template:"")},t.appendChild(r)});const u=d.find(e=>e.id===c);u?(n.style.display="block",n.textContent=("PROMPT"===u.id?"Full line: @@PROMPT ":"Template: ")+(u.template||"")):n.style.display="none"}catch(o){"undefined"!=typeof console&&console.warn("chatAtAtInput",o)}},chatKeydown:function(e){const t=document.getElementById("chatAtAtMenu");if(t&&"block"===t.style.display&&("Enter"===e.key||"Tab"===e.key)){const n=t.firstElementChild;if(n)return e.preventDefault(),void n.click()}"Enter"!==e.key||e.shiftKey||(e.preventDefault(),M()),!t||"block"!==t.style.display||"Escape"!==e.key&&"Tab"!==e.key||(t.style.display="none")},sendChat:M,sendDirectAgent:z,loadChatAgentSelector:_,clearChatHistory:async function(){if(!confirm("Clear chat history for this session?"))return;const e=document.getElementById("chatMessages");e.innerHTML="",e.dataset.historyLoaded="false",localStorage.removeItem(I),await o("/api/crew-lead/clear",{sessionId:l()}).catch(()=>{}),await A()},restorePassthroughLog:function(){var e;try{const t=JSON.parse(localStorage.getItem(I)||"[]");if(!t.length)return;const n=document.getElementById("chatMessages");if(!n)return;(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)&&0===n.children.length&&(O(t),n.scrollTop=n.scrollHeight)}catch{}},sendPassthrough:B,stopAll:async function(){if(confirm("Stop all running pipelines?"))try{await o("/api/crew-lead/chat",{message:"@@STOP",sessionId:l()}),r("⏹ Stop signal sent")}catch(e){r("Failed: "+e.message,!0)}},killAll:async function(){if(confirm("Kill all agents? Bridges must be restarted after."))try{await o("/api/crew-lead/chat",{message:"@@KILL",sessionId:l()}),r("☠️ Kill signal sent")}catch(e){r("Failed: "+e.message,!0)}},killPassthrough:function(){j&&(j.abort(),j=null)},refreshSessionIndicator:H,clearPassthroughSession:async function(){var e;const t=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!t)return;const n=E(),o=n&&i.projectsData[n],a=(null==o?void 0:o.outputDir)||null;if(!a)return;const s=`${t}:${a}:${l()||"owner"}`,c=`${t}:${a}`;try{await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(s)}`,{method:"DELETE"}),await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(c)}`,{method:"DELETE"}),r("Session cleared — next message starts fresh"),H()}catch(d){r("Failed: "+d.message,!0)}},resetSendButton:function(){const e=document.querySelector('[data-action="sendChat"]');e&&(e.textContent="Send",e.className="btn-green",e.disabled=!1)},handleImageUpload:F,toggleVoiceRecording:async function(){const e=document.getElementById("recordVoiceBtn");if(P&&"inactive"!==P.state)P.stop(),e.textContent="🎤",e.style.background="";else try{const t=await navigator.mediaDevices.getUserMedia({audio:!0});N=[],P=new MediaRecorder(t,{mimeType:"audio/webm"}),P.ondataavailable=e=>{e.data.size>0&&N.push(e.data)},P.onstop=async()=>{const e=new Blob(N,{type:"audio/webm"});t.getTracks().forEach(e=>e.stop()),s("user",`🎤 [Voice message recorded - ${(e.size/1024).toFixed(0)} KB]`),s("assistant","🎤 Transcribing voice...");try{const t=new FormData;t.append("audio",e,"voice.webm");const o=new AbortController,a=setTimeout(()=>o.abort(),6e4),r=await fetch("/api/transcribe-audio",{method:"POST",body:t,signal:o.signal});let i;clearTimeout(a);try{i=await r.json()}catch(n){return s("assistant",`⚠️ Transcription error: Server returned invalid response (${r.status})`),void(N=[])}if(i.ok&&i.transcription){s("assistant",`**Transcription:**\n\n"${i.transcription}"`);const e=document.getElementById("chatInput");e.value=i.transcription,e.focus()}else s("assistant",`⚠️ Transcription failed: ${i.error||"No result"}`)}catch(o){const e=o.message||String(o);s("assistant",`⚠️ Transcription error: ${e}${"Failed to fetch"===e?" (Is the dashboard running on port 4319? Try: npm run restart-dashboard)":""}`)}N=[]},P.start(),e.textContent="⏹️",e.style.background="var(--red, #ef4444)",r("🎤 Recording... Click again to stop")}catch(t){r("⚠️ Microphone access denied: "+t.message,!0)}}}}"undefined"!=typeof window&&(window.toggleUnifiedView=async function(){o=!o;const a=document.getElementById("unifiedViewToggle");o?(a.style.background="var(--accent)",a.style.color="#fff",a.textContent="📊 Unified ✓",e("Unified view enabled — showing all sources")):(a.style.background="",a.style.color="",a.textContent="📊 Unified View",e("Standard view restored")),await async function(){const a=t.chatActiveProjectId;if(a&&"general"!==a)if(o)try{const t=await n(`/api/crew-lead/project-messages?projectId=${encodeURIComponent(a)}&limit=100`);if(!t.ok)return console.error("Failed to load unified messages:",t.error),void e("Failed to load unified view",!0);const o=document.getElementById("chatMessages");if(!o)return;o.innerHTML="";const s={dashboard:"💻",cli:"⚡","sub-agent":"👷",agent:"🤖"};for(const e of t.messages){const t=document.createElement("div");t.className=`chat-bubble ${e.role}`;const n=s[e.source]||"📝",a=e.agent?` [${e.agent}]`:"",r=new Date(e.ts).toLocaleTimeString();t.innerHTML=`\n <div style="font-size:10px;color:var(--text-3);margin-bottom:4px;">\n ${n} <strong>${e.source}</strong>${a} · ${r}\n </div>\n <div style="white-space:pre-wrap;word-break:break-word;">${i(e.content)}</div>\n `,o.appendChild(t)}o.scrollTop=o.scrollHeight,e(`Loaded ${t.messages.length} messages from all sources`)}catch(s){console.error("Failed to load unified messages:",s),e("Failed to load unified view",!0)}else window.loadChatHistory&&await window.loadChatHistory()}()},window.openSearchModal=a,window.closeSearchModal=s,window.performSearch=r,window.exportMessages=async function(){const n=t.chatActiveProjectId;if(!n||"general"===n)return void e("Export requires an active project",!0);const o=await new Promise(e=>{const t=document.createElement("div");t.style.cssText="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:10001;display:flex;align-items:center;justify-content:center;",t.innerHTML='\n <div style="background:var(--bg-card);border-radius:12px;padding:24px;max-width:400px;">\n <h3 style="margin:0 0 16px 0;">Export Format</h3>\n <div style="display:flex;flex-direction:column;gap:8px;margin-bottom:16px;">\n <button class="export-format-btn btn-ghost" data-format="markdown" style="text-align:left;padding:12px;">\n 📝 Markdown (.md) — Best for reading\n </button>\n <button class="export-format-btn btn-ghost" data-format="json" style="text-align:left;padding:12px;">\n 📋 JSON — Full data with metadata\n </button>\n <button class="export-format-btn btn-ghost" data-format="csv" style="text-align:left;padding:12px;">\n 📊 CSV — Spreadsheet compatible\n </button>\n <button class="export-format-btn btn-ghost" data-format="txt" style="text-align:left;padding:12px;">\n 📄 Plain Text (.txt)\n </button>\n </div>\n <button onclick="this.closest(\'div\').parentElement.remove()" class="btn-ghost" style="width:100%;">Cancel</button>\n </div>\n ',document.body.appendChild(t),t.querySelectorAll(".export-format-btn").forEach(n=>{n.onclick=()=>{e(n.dataset.format),t.remove()}}),t.onclick=n=>{n.target===t&&(e(null),t.remove())}});if(o)try{e("Exporting...");const t=`/api/crew-lead/export-project-messages?projectId=${encodeURIComponent(n)}&format=${o}&includeMetadata=true`,a=document.createElement("a");a.href=t,a.download=`project-${n}.${"markdown"===o?"md":o}`,document.body.appendChild(a),a.click(),document.body.removeChild(a),e(`Exported as ${o.toUpperCase()}`)}catch(a){console.error("Export failed:",a),e("Export failed: "+a.message,!0)}}),"undefined"!=typeof window&&document.addEventListener("keydown",e=>{if((e.metaKey||e.ctrlKey)&&"k"===e.key){const n=t.chatActiveProjectId;n&&"general"!==n&&(e.preventDefault(),a())}if("Escape"===e.key){const e=document.getElementById("searchModal");e&&"none"!==e.style.display&&s()}"Enter"===e.key&&"searchInput"===e.target.id&&(e.preventDefault(),r())});export{y as i};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tab-benchmarks-tab-BHjKCPm3.js","assets/core-utils-CmOkXgzi.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-CmOkXgzi.js";import{c as v}from"./setup-wizard-CA0Or47w.js";import{i as f}from"./components-BS9fQjE_.js";import{s as y}from"./orchestration-Ca2DLWN-.js";import"./cli-process-COMRNPqr.js";import{i as w}from"./chat-core-3KirthZA.js";import{i as b,s as x,h as C}from"./tab-swarm-chat-tab-BNrd88-r.js";import{i as k}from"./tab-waves-tab-SaJDkb4x.js";import{i as E,s as I}from"./tab-workflows-tab-B-soSy1k.js";import{c as T,m as B,s as S,l as j,a as A}from"./tab-memory-tab-Cu6u13EQ.js";import{i as P,s as L,l as M,a as _,r as N}from"./tab-services-tab-DU_LH3uG.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-BgpIsjkw.js";import{i as ce,a as de}from"./tab-prompts-tab-DVkUNaJd.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 Ce,u as ke}from"./tab-skills-tab-BpY0uZHW.js";import{s as Ee,i as Ie,a as Te,l as Be}from"./tab-contacts-tab-DiOyMYth.js";import{i as Se,t as je,l as Ae,d as Pe}from"./tab-engines-tab-BsdZVvU0.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-B1AcjL1W.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-BLEjmd19.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,m as mt,u 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 Ct,z as kt,A as Et,B as It,C as Tt,D as Bt,E as St,F as jt,G as At,H as Pt,I as Lt,J as Mt}from"./tab-settings-tab-BselH1c0.js";import{i as _t,s as Nt,l as Rt,a as Ot,b as Ft,c as Ht,d as Dt,e as zt,f as Gt,g as $t,h as Vt,r as qt,j as Kt}from"./tab-comms-tab-kguqTIzD.js";import{i as Ut,p as Wt,r as Jt,c as Qt,a as Yt,b as Xt,e as Zt,d as en,l as tn,o as nn,f as on,h as an,j as sn,k as rn,m as ln,n as cn,q as dn,t as pn,v as mn,w as un}from"./tab-projects-tab-SFH4E--a.js";import{a as gn,r as hn,c as vn,b as fn,l as yn,d as wn}from"./tab-usage-tab-BIOOnB-Y.js";import{s as bn,r as xn,l as Cn,a as kn,b as En}from"./tab-spending-tab-DEccQHnt.js";import{i as In}from"./tab-pm-loop-tab-DiAPTJXu.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 Tn={};let Bn=null;async function Sn(){return Bn||(Bn=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 Tn)return;Tn[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-BHjKCPm3.js"),__vite__mapDeps([0,1]))),Bn}async function jn(){try{const e=document.getElementById("statusDot");document.getElementById("status").textContent="online",e.className="status-dot online",await vn();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 An(){await jn()}function Pn(e){document.querySelectorAll(".nav-item").forEach(e=>e.classList.remove("active"));const t=document.getElementById(e);t&&t.classList.add("active")}function Ln(){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 Mn(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 _n(){const e=(location.hash||"#chat").slice(1),t=(e.split("?")[0]||"chat").split("/");return{view:t[0]||"chat",subtab:t[1],raw:e}}function Nn(){return _n().view}function Rn(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 On(){try{const e=await a("/api/ui/active-project");return String((null==e?void 0:e.projectId)||"").trim()||"general"}catch{return"general"}}async function Fn(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 Hn(){Ln(),document.getElementById("chatView").classList.add("active"),Pn("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 Zn();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(),Wt(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 On();try{o.chatActiveProjectId=e||localStorage.getItem("crewswarm_chat_active_project_id")||"general"}catch{o.chatActiveProjectId=e||"general"}}window.location.hash.includes("?project=")||Rn(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),Fn(o.chatActiveProjectId),vn(),$n(),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 Xn()}function Dn(){Ln(),document.getElementById("filesView").classList.add("active"),Pn("navFiles"),o.activeTab="files",s(),uo()}function zn(){return"owner"}P({hideAllViews:Ln,setNavActive:Pn}),R({hideAllViews:Ln,setNavActive:Pn,refreshAgents:F}),ce({hideAllViews:Ln,setNavActive:Pn}),He({hideAllViews:Ln,setNavActive:Pn}),k(),E({hideAllViews:Ln,setNavActive:Pn});let Gn=null;function $n(){if(Gn)return;const e=`http://${window.location.hostname||"127.0.0.1"}:5010/events`;console.log("[crewswarm] Starting EventSource listener for",e),Gn=new EventSource(e);const t="undefined"!=typeof localStorage&&"1"===localStorage.getItem("crewswarm_debug_sse");Gn.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(C(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===Yn)return console.log("[crewswarm] Skipping SSE echo of locally-sent message"),void(Yn=null);a.content!==Qn?(console.log("[crewswarm] Appending user bubble:",a.content.slice(0,50)),g("user",a.content),Qn=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 Jn=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,Jn=a.content}else{t&&t.remove();const e=a.content===Jn&&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),Jn=a.content)}}return void(l&&(l.scrollTop=l.scrollHeight))}if("pending_project"===a.type&&"owner"===a.sessionId&&a.pendingProject&&l)return Wn(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 en(),e&&un(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")&&wn(window._telemetryEvents)}}catch{}else console.warn("[crewswarm] SSE message with null/empty data")},Gn.onopen=()=>{console.log("[crewswarm] SSE connection opened"),window._sseReconnectDelay=2e3},Gn.onerror=e=>{console.error("[crewswarm] SSE error:",e),Gn.close(),Gn=null,window._sseReconnectTimer&&clearTimeout(window._sseReconnectTimer),window._sseReconnectTimer=setTimeout(()=>{window._sseReconnectTimer=null,window._sseReconnectDelay=Math.min(2*(window._sseReconnectDelay||2e3),3e4),$n()},window._sseReconnectDelay||2e3)}}const Vn=[{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 qn(){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="",Vn.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)),qn()};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(Vn.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)),qn()},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 Kn(){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="",qn())}window._telemetryEvents=window._telemetryEvents||[];const Un=()=>yn(En);function Wn(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 Jn="",Qn="",Yn=null;const{loadChatHistory:Xn,waitForChatHistoryIdle:Zn,chatAtAtInput:eo,chatKeydown:to,sendChat:no,clearChatHistory:oo,stopAll:ao,killAll:so,killPassthrough:io,refreshSessionIndicator:ro,clearPassthroughSession:lo,resetSendButton:co,handleImageUpload:po,toggleVoiceRecording:mo}=w({postJSON:r,getJSON:a,appendChatBubble:g,showNotification:i,state:o,getChatSessionId:()=>"owner",getChatActiveProjectId:()=>o.chatActiveProjectId,getCrewLeadInfo:()=>window._crewLeadInfo,appendRoadmapCard:Wn,getLastAppendedAssistantContent:()=>Jn,setLastAppendedAssistantContent:e=>{Jn=e},setLastAppendedUserContent:e=>{Qn=e},setLastSentContent:e=>{Yn=e}});async function uo(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=vo(e.mtime),a=fo(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 go(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 ho(){const e=document.getElementById("file-preview-pane");e&&(e.style.display="none")}function vo(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 fo(e){return e<1024?e+"B":e<1048576?(e/1024).toFixed(1)+"KB":(e/1024/1024).toFixed(1)+"MB"}function yo(){Ln(),document.getElementById("settingsView").classList.add("active"),Pn("navSettings"),o.activeTab="settings",s();const e=(location.hash||"").replace("#settings/",""),t={system:"engines",telegram:"comms",whatsapp:"comms"}[e]||e;wo(["usage","engines","comms","security","webhooks"].includes(t)?t:"usage")}function wo(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&&(fn(),kn()),"engines"===e&&(ft(),yt(),wt(),bt(),xt(),Ct(),kt(),Et(),It(),Tt(),Bt(),St(),jt(),At(),Pt()),"comms"===e&&Kt(),"security"===e&&(qn(),Lt()),(null==(t=document.getElementById("settingsView"))?void 0:t.classList.contains("active"))&&history.replaceState(null,"","#settings/"+e)}function bo(){Ln(),document.getElementById("enginesView").classList.add("active"),Pn("navEngines"),Ae()}null==(e=document.getElementById("attachImageBtn"))||e.addEventListener("click",()=>{document.getElementById("imageUpload").click()}),null==(t=document.getElementById("imageUpload"))||t.addEventListener("change",po),null==(n=document.getElementById("recordVoiceBtn"))||n.addEventListener("click",mo),window.loadChatHistory=Xn,window.getChatSessionId=zn,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");Rn(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{}Fn(t),console.log("🔵 [TAB CLICK] Updated state:",{projectId:o.chatActiveProjectId,sessionId:"owner",url:window.location.hash}),console.log("🔵 [TAB CLICK] Calling loadChatHistory()..."),Xn().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"!==_n().view)return;const e=await On(),t=e&&"undefined"!==e?e:"general";t!==(o.chatActiveProjectId&&"undefined"!==o.chatActiveProjectId?o.chatActiveProjectId:"general")&&window.selectProjectTab&&window.selectProjectTab(t)})().catch(()=>{})}),_t({showSettings:yo,showSettingsTab:wo}),Mt({getModels:F,populateModelDropdown:le}),Ye({hideAllViews:Ln,setNavActive:Pn,loadAgents:F}),De(),b({hideAllViews:Ln,setNavActive:Pn});const xo=async()=>{const{showBenchmarks:e}=await Sn();e({hideAllViews:Ln,setNavActive:Pn})};function Co(){Ln(),document.getElementById("memoryView").classList.add("active"),Pn("navMemory"),A()}function ko(){Ln(),document.getElementById("cliProcessView").classList.add("active"),Pn("navCLI"),window.initCLIProcess&&window.initCLIProcess()}function Eo(){Ln(),document.getElementById("toolMatrixView").classList.add("active"),Pn("navToolMatrix"),gn()}async function Io(){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 To(){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 Bo(){sn({hideAllViews:Ln,setNavActive:Pn})}function So(){an({hideAllViews:Ln,setNavActive:Pn})}Ut({showChat:Hn,showBuild:Bo}),jn(),setInterval(jn,3e4),(async()=>{try{const e=(await a("/api/projects")).projects||[];o.projectsData={},e.forEach(e=>{o.projectsData[e.id]=e}),Wt(e),s(),"#projects"===location.hash&&So()}catch{}})(),document.getElementById("refreshBtn").onclick=An,document.getElementById("runBuildBtn").onclick=Jt,document.getElementById("continuousBuildBtn").onclick=Qt,document.getElementById("stopBuildBtn").onclick=Yt,document.getElementById("stopContinuousBtn").onclick=Xt,document.getElementById("enhancePromptBtn").onclick=Zt,In(),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="",en()}catch(a){i("Failed: "+a.message,!0)}else i("Name and output directory required",!0)};const jo={chat:Hn,"swarm-chat":x,swarm:_e,rt:Me,dlq:Le,files:Dn,services:L,agents:O,models:ze,settings:yo,engines:bo,skills:me,"run-skills":pe,benchmarks:xo,"tool-matrix":Eo,build:Bo,messaging:Nt,projects:So,contacts:Ee,memory:Co,workflows:I,"cli-process":ko,prompts:de};for(const[_o,No]of Object.entries(jo)){const e=No,t=function(...t){const n=location.hash||"";return"chat"===_o?n.startsWith("#chat")||history.replaceState(null,"","#chat"):history.replaceState(null,"","#"+_o),e(...t)};jo[_o]=t,window[e.name]=t}function Ao(e){const t=String(e||"chat").split("?")[0].split("/")[0];(jo[t]||jo.chat)()}(async()=>{if(await v())return;const{view:e,subtab:t}=_n();"1"===new URLSearchParams(window.location.search).get("focus")?setTimeout(()=>{const e=document.getElementById("chatInput");e&&(Ao("chat"),e.focus())},500):(Ao(e||"chat"),"settings"===e&&t&&wo(t))})(),window.addEventListener("hashchange",()=>{const{view:e,subtab:t}=_n(),n=Mo[e];n?(n(),"settings"===e&&t&&wo(t)):Hn()}),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)),An(),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 Po={showChat:Hn,showSwarm:_e,showRT:Me,showBuild:Bo,showFiles:Dn,showDLQ:Le,showProjects:So,showAgents:O,showModels:ze,showEngines:bo,showSkills:me,showRunSkills:pe,showBenchmarks:xo,showToolMatrix:Eo,showServices:L,showSettings:yo,pickFolder:e=>Mn(e),loadFiles:e=>uo(),clearChatHistory:oo,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:no,stopAll:ao,killAll:so,stopPassthrough:io,clearPassthroughSession:lo,loadServices:M,saveRTToken:ht,lockConfig:gt,unlockConfig:ut,startCrew:H,toggleEmojiPicker:e=>oe(e),bulkSetRoute:(e,t)=>ae(e,t),loadSpending:Cn,resetSpending:xn,saveGlobalCaps:bn,loadOcStats:Un,addAllowlistPattern:Kn,sendTestWebhook:Io,startTgBridge:Vt,stopTgBridge:$t,saveTgConfig:Gt,loadTelegramSessions:zt,loadTgMessages:Dt,startWaBridge:Ht,stopWaBridge:Ft,saveWaConfig:Ot,loadWaMessages:Rt,saveOpencodeSettings:mt,saveOpencodeModel:pt,saveGlobalFallback:dt,toggleBgConsciousness:ct,toggleCursorWaves:lt,toggleTmuxBridge: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 Sn()).loadBenchmarks(),loadBenchmarkLeaderboard:async()=>(await Sn()).loadBenchmarkLeaderboard(),loadBenchmarkTasks:async()=>(await Sn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Sn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Sn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Sn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadEngines:Ae,toggleImportEngine:je,importEngineFromUrl:Se,deleteEngine:e=>Pe(e),loadToolMatrix:gn,loadBuildProjectPicker:tn,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:ho,previewFile:(e,t)=>go(e),replayDLQ:e=>Fe(e),deleteDLQ:e=>Oe(e),runSkillFromUI:e=>be(e),editSkill:e=>xe(e),deleteSkill:e=>Ce(e),restartAgentFromUI:e=>hn(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?pn(e):mn(e)},"edit-roadmap":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&dn(e,n.roadmapFile)},"retry-failed":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&cn(n.roadmapFile)},"save-roadmap":e=>ln(e),"reset-failed":e=>rn(e),showSettingsTab:e=>wo(e)};let Lo=!1;document.addEventListener("touchstart",e=>{if(!(e.target instanceof Element))return;e.target.closest("[data-action]")&&(Lo=!0,setTimeout(()=>{Lo=!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(Lo)return void e.preventDefault();e.stopPropagation();const n=t.dataset.action,o=Po[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=Po[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(Nn()!==n)return void(window.location.hash=n);const o=Mo[n];o&&o()})});const t=document.getElementById("chatInput");t&&!t.dataset.boundChatComposer&&(t.dataset.boundChatComposer="1",t.addEventListener("keydown",to),t.addEventListener("input",eo));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(),no()}));const o=document.getElementById("cmdAllowlistInput");o&&o.addEventListener("keydown",e=>{"Enter"===e.key&&Kn()});const a=document.getElementById("waAllowedNumbers");a&&a.addEventListener("input",qt);const s=document.getElementById("skillSearch");s&&s.addEventListener("input",e=>we(e.target.value));const i=document.getElementById("passthroughEngine");i&&i.addEventListener("change",()=>{ro(),function(){const e=document.getElementById("passthroughEngine"),t=document.getElementById("passthroughModel");if(!e||!t)return;const n=e.value,o={cursor:[{value:"",label:"— default (composer-2-fast) —"},{optgroup:"Cursor Defaults"},{value:"composer-2-fast",label:"🟢 Composer 2 Fast (default)"},{value:"composer-2-thinking",label:"Composer 2 Thinking"},{optgroup:"Recommended (No Rate Limits)"},{value:"gpt-5.4",label:"🟢 GPT-5.4"},{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.6",label:"🟡 Claude 4.6 Sonnet (current)"},{value:"opus-4.6",label:"🟡 Claude 4.6 Opus"},{optgroup:"Thinking Models (Slower)"},{value:"sonnet-4.6-thinking",label:"Claude 4.6 Sonnet Thinking"},{value:"opus-4.6-thinking",label:"Claude 4.6 Opus Thinking"},{optgroup:"Compatible Claude Models"},{value:"sonnet-4.5",label:"Claude 4.5 Sonnet"},{value:"opus-4.5",label:"Claude 4.5 Opus"},{value:"sonnet-4.5-thinking",label:"Claude 4.5 Sonnet 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.4) —"},{optgroup:"Recommended"},{value:"gpt-5.4",label:"🟢 GPT-5.4 (current)"},{value:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{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.4",label:"GPT 5.4 ($3/$15)"},{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)}}(),co()});const r=document.getElementById("chatProjectSelect");r&&r.addEventListener("change",ro);const l=document.getElementById("passthroughModel");l&&l.addEventListener("change",()=>{co()})},{once:!0});const Mo={chat:Hn,"swarm-chat":x,swarm:_e,rt:Me,build:Bo,files:Dn,dlq:Le,projects:So,contacts:Ee,agents:O,models:ze,engines:bo,skills:me,"run-skills":pe,waves:()=>{Ln(),document.getElementById("wavesView").style.display="block",Pn("navWaves")},workflows:I,benchmarks:xo,"tool-matrix":Eo,memory:Co,"cli-process":ko,services:L,prompts:de,settings:yo};document.addEventListener("click",e=>{const t=e.target.closest("[data-view]");if(t){const e=t.dataset.view,n=Mo[e];return void(n&&(Nn()!==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}`,wo(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:Kn,applyNewAgentToolPreset:ie,applyPromptPreset:se,bulkSetRoute:ae,cancelSkillForm:ge,chatAtAtInput:eo,chatKeydown:to,clearChatHistory:oo,filterSkills:we,loadAllUsage:kn,loadBenchmarkLeaderboard:async()=>(await Sn()).loadBenchmarkLeaderboard(),loadBenchmarks:async()=>(await Sn()).loadBenchmarks(),loadBenchmarkTasks:async()=>(await Sn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Sn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Sn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Sn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadBuildProjectPicker:tn,loadFiles:uo,loadOcStats:Un,loadRunSkills:ue,loadServices:M,loadSpending:Cn,loadTelegramSessions:zt,loadTgMessages:Dt,loadToolMatrix:gn,loadWaMessages:Rt,onBuildProjectChange:on,onChatProjectChange:nn,pickFolder:Mn,renderWaContactRows:qt,resetSpending:xn,approveSkill:async function(e){try{await fetch("/api/skills/approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Approved"),To()}catch(t){i("Failed: "+t.message,"error")}},loadPendingApprovals:To,rejectSkill:async function(e){try{await fetch("/api/skills/reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Rejected"),To()}catch(t){i("Failed: "+t.message,"error")}},saveGlobalCaps:bn,saveGlobalFallback:dt,saveBgConsciousnessModel:vt,saveOpencodeSettings:mt,saveRTToken:ht,saveSkill:he,saveTgConfig:Gt,saveWaConfig:Ot,sendChat:no,sendTestWebhook:Io,showAgents:O,showBenchmarks:xo,showBuild:Bo,showChat:Hn,showContacts:Ee,showDLQ:Le,showFiles:Dn,showModels:ze,showProjects:So,showRT:Me,showRunSkills:pe,showServices:L,showSettings:yo,showSettingsTab:wo,showSkills:me,showSwarm:_e,showToolMatrix:Eo,showMemoryView:Co,startCrew:H,startTgBridge:Vt,startWaBridge:Ht,stopTgBridge:$t,stopWaBridge:Ft,toggleAddSkill:ye,toggleBgConsciousness:ct,toggleCursorWaves:lt,toggleTmuxBridge:rt,toggleClaudeCode:st,toggleEmojiPicker:oe,updateSkillAuthFields:ke,navigateTo:Ao,renderStatusBadge:p,showLoading:d,showEmpty:c,showError:l,loadContacts:Be,applyContactFilters:Te,applyToolPreset:ne,closePreviewPane:ho,deleteAgent:te,deleteSkill:Ce,editSkill:xe,fetchBuiltinModels:Qe,fetchModels:Je,previewFile:go,resetAgentSession:ee,restartAgentFromUI:hn,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});
@@ -1 +1 @@
1
- import{s as e}from"./core-utils-CmOkXgzi.js";import{l as t,g as n}from"./tab-projects-tab-DhNWnlzt.js";let o=null;function d(){const e=document.getElementById("buildProjectPicker");return e?e.value:""}async function l(){try{const e=d(),t=e?"?projectId="+encodeURIComponent(e):"",n=await fetch("/api/pm-loop/status"+t).then(e=>e.json()),l=document.getElementById("pmLoopBadge"),i=document.getElementById("pmStartBtn"),p=document.getElementById("pmDryRunBtn"),s=document.getElementById("pmLiveLog");n.running?(l.textContent="running (pid "+n.pid+")",l.classList.add("running"),i.disabled=!0,p.disabled=!0,s.style.display="block",o||a()):l.textContent.startsWith("running")&&(l.textContent="idle",l.classList.remove("running"),i.disabled=!1,p.disabled=!1)}catch(e){}}function a(){o||(o=setInterval(async()=>{try{const e=await fetch("/api/pm-loop/log").then(e=>e.json()),t=document.getElementById("pmLiveLog"),n=document.getElementById("pmLoopBadge"),d=document.getElementById("pmStartBtn"),l=document.getElementById("pmDryRunBtn");if(e.lines&&e.lines.length){t.textContent=e.lines.map(e=>{if("finish"===e.event)return`🏁 Done ✓${e.done} ✗${e.failed} ⏳${e.pending}`;if("stopped_by_file"===e.event)return"⛔ Stopped by user";if("all_done"===e.event)return`🏁 All ${e.total} items complete!`;return`${"done"===e.status?"✅":"failed"===e.status?"❌":(e.event,"·")} ${e.item?`${e.item.substring(0,60)}`:e.event||""}`}).join("\n"),t.scrollTop=t.scrollHeight;const a=e.lines[e.lines.length-1];!a||"finish"!==a.event&&"all_done"!==a.event&&"stopped_by_file"!==a.event||(clearInterval(o),o=null,n.textContent="all_done"===a.event?"✓ complete":"idle",n.classList.remove("running"),d.disabled=!1,l.disabled=!1)}}catch(e){}},5e3))}async function i(t=!1){var o,l,i,p,s,m,c,r,u,g;const y=d(),I=document.getElementById("pmLoopBadge");document.getElementById("pmStatus");const B=document.getElementById("pmLiveLog"),f=document.getElementById("pmStartBtn"),h=document.getElementById("pmDryRunBtn"),v=n(y);if(y)try{I.textContent=t?"dry run...":"starting...",I.classList.add("running"),f.disabled=!0,h.disabled=!0,B.style.display="block",B.textContent="⚙ Starting PM Loop for "+(v?v.name:y)+(t?" (dry run)":"")+"...\n";const n=await fetch("/api/pm-loop/start",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({dryRun:t,projectId:y,pmOptions:{useQA:(null==(o=document.getElementById("pmOptQA"))?void 0:o.checked)??!0,useSecurity:(null==(l=document.getElementById("pmOptSecurity"))?void 0:l.checked)??!0,useSpecialists:(null==(i=document.getElementById("pmOptSpecialists"))?void 0:i.checked)??!0,selfExtend:(null==(p=document.getElementById("pmOptSelfExtend"))?void 0:p.checked)??!0,maxItems:parseInt((null==(s=document.getElementById("pmOptMaxItems"))?void 0:s.value)||"200"),taskTimeoutMin:parseInt((null==(m=document.getElementById("pmOptTimeout"))?void 0:m.value)||"10"),extendEveryN:parseInt((null==(c=document.getElementById("pmOptExtendN"))?void 0:c.value)||"5"),pauseSec:parseInt((null==(r=document.getElementById("pmOptPause"))?void 0:r.value)||"5"),maxRetries:parseInt((null==(u=document.getElementById("pmOptMaxRetries"))?void 0:u.value)||"2"),coderAgent:(null==(g=document.getElementById("pmOptCoder"))?void 0:g.value.trim())||"crew-coder"}})}),d=await n.json();if(409===n.status||d.alreadyRunning)return B.textContent="⚠ Already running (pid "+d.pid+"). Watch the log below.\n",I.textContent="running (pid "+d.pid+")",e("PM Loop already running for this project (pid "+d.pid+")",!0),void a();B.textContent+="✅ Spawned (pid "+d.pid+"). PM is reading roadmap...\n",I.textContent="running (pid "+d.pid+")",e("PM Loop started"+(t?" (dry run)":"")+" for "+(v?v.name:y)),a()}catch(E){e("PM Loop failed: "+E.message,!0),I.textContent="idle",I.classList.remove("running"),f.disabled=!1,h.disabled=!1}else e("Select a project first from the Project picker above",!0)}async function p(){const t=d();try{await fetch("/api/pm-loop/stop",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({projectId:t})}),e("Stop signal sent — PM will finish current task then halt."),document.getElementById("pmLoopBadge").textContent="stopping..."}catch(n){e("Stop failed: "+n.message,!0)}}async function s(){const e=document.getElementById("pmRoadmapPanel");if("none"===e.style.display)try{await t();const o=d(),l=n(o);console.log("[toggleRoadmap] projectId:",o,"proj:",l);let a="";if(l&&l.roadmapFile){console.log("[toggleRoadmap] Fetching project roadmap:",l.roadmapFile);a=(await fetch("/api/file-content?path="+encodeURIComponent(l.roadmapFile)).then(e=>e.json())).content||"(empty)"}else{console.log("[toggleRoadmap] Using default roadmap (no project selected or no roadmapFile)");a=(await fetch("/api/pm-loop/roadmap").then(e=>e.json())).content||"(empty)"}e.textContent=a,e.style.display="block"}catch(o){console.error("[toggleRoadmap] Error:",o),e.textContent="Could not load roadmap: "+o.message,e.style.display="block"}else e.style.display="none"}function m(){document.getElementById("pmStartBtn").onclick=()=>i(!1),document.getElementById("pmDryRunBtn").onclick=()=>i(!0),document.getElementById("pmStopBtn").onclick=p,document.getElementById("pmRoadmapBtn").onclick=s,t().then(()=>l()),document.getElementById("buildProjectPicker").addEventListener("change",()=>{o&&(clearInterval(o),o=null),l()})}export{m as i};
1
+ import{s as e}from"./core-utils-CmOkXgzi.js";import{l as t,g as n}from"./tab-projects-tab-SFH4E--a.js";let o=null;function d(){const e=document.getElementById("buildProjectPicker");return e?e.value:""}async function l(){try{const e=d(),t=e?"?projectId="+encodeURIComponent(e):"",n=await fetch("/api/pm-loop/status"+t).then(e=>e.json()),l=document.getElementById("pmLoopBadge"),i=document.getElementById("pmStartBtn"),p=document.getElementById("pmDryRunBtn"),s=document.getElementById("pmLiveLog");n.running?(l.textContent="running (pid "+n.pid+")",l.classList.add("running"),i.disabled=!0,p.disabled=!0,s.style.display="block",o||a()):l.textContent.startsWith("running")&&(l.textContent="idle",l.classList.remove("running"),i.disabled=!1,p.disabled=!1)}catch(e){}}function a(){o||(o=setInterval(async()=>{try{const e=await fetch("/api/pm-loop/log").then(e=>e.json()),t=document.getElementById("pmLiveLog"),n=document.getElementById("pmLoopBadge"),d=document.getElementById("pmStartBtn"),l=document.getElementById("pmDryRunBtn");if(e.lines&&e.lines.length){t.textContent=e.lines.map(e=>{if("finish"===e.event)return`🏁 Done ✓${e.done} ✗${e.failed} ⏳${e.pending}`;if("stopped_by_file"===e.event)return"⛔ Stopped by user";if("all_done"===e.event)return`🏁 All ${e.total} items complete!`;return`${"done"===e.status?"✅":"failed"===e.status?"❌":(e.event,"·")} ${e.item?`${e.item.substring(0,60)}`:e.event||""}`}).join("\n"),t.scrollTop=t.scrollHeight;const a=e.lines[e.lines.length-1];!a||"finish"!==a.event&&"all_done"!==a.event&&"stopped_by_file"!==a.event||(clearInterval(o),o=null,n.textContent="all_done"===a.event?"✓ complete":"idle",n.classList.remove("running"),d.disabled=!1,l.disabled=!1)}}catch(e){}},5e3))}async function i(t=!1){var o,l,i,p,s,m,c,r,u,g;const y=d(),I=document.getElementById("pmLoopBadge");document.getElementById("pmStatus");const B=document.getElementById("pmLiveLog"),f=document.getElementById("pmStartBtn"),h=document.getElementById("pmDryRunBtn"),v=n(y);if(y)try{I.textContent=t?"dry run...":"starting...",I.classList.add("running"),f.disabled=!0,h.disabled=!0,B.style.display="block",B.textContent="⚙ Starting PM Loop for "+(v?v.name:y)+(t?" (dry run)":"")+"...\n";const n=await fetch("/api/pm-loop/start",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({dryRun:t,projectId:y,pmOptions:{useQA:(null==(o=document.getElementById("pmOptQA"))?void 0:o.checked)??!0,useSecurity:(null==(l=document.getElementById("pmOptSecurity"))?void 0:l.checked)??!0,useSpecialists:(null==(i=document.getElementById("pmOptSpecialists"))?void 0:i.checked)??!0,selfExtend:(null==(p=document.getElementById("pmOptSelfExtend"))?void 0:p.checked)??!0,maxItems:parseInt((null==(s=document.getElementById("pmOptMaxItems"))?void 0:s.value)||"200"),taskTimeoutMin:parseInt((null==(m=document.getElementById("pmOptTimeout"))?void 0:m.value)||"10"),extendEveryN:parseInt((null==(c=document.getElementById("pmOptExtendN"))?void 0:c.value)||"5"),pauseSec:parseInt((null==(r=document.getElementById("pmOptPause"))?void 0:r.value)||"5"),maxRetries:parseInt((null==(u=document.getElementById("pmOptMaxRetries"))?void 0:u.value)||"2"),coderAgent:(null==(g=document.getElementById("pmOptCoder"))?void 0:g.value.trim())||"crew-coder"}})}),d=await n.json();if(409===n.status||d.alreadyRunning)return B.textContent="⚠ Already running (pid "+d.pid+"). Watch the log below.\n",I.textContent="running (pid "+d.pid+")",e("PM Loop already running for this project (pid "+d.pid+")",!0),void a();B.textContent+="✅ Spawned (pid "+d.pid+"). PM is reading roadmap...\n",I.textContent="running (pid "+d.pid+")",e("PM Loop started"+(t?" (dry run)":"")+" for "+(v?v.name:y)),a()}catch(E){e("PM Loop failed: "+E.message,!0),I.textContent="idle",I.classList.remove("running"),f.disabled=!1,h.disabled=!1}else e("Select a project first from the Project picker above",!0)}async function p(){const t=d();try{await fetch("/api/pm-loop/stop",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({projectId:t})}),e("Stop signal sent — PM will finish current task then halt."),document.getElementById("pmLoopBadge").textContent="stopping..."}catch(n){e("Stop failed: "+n.message,!0)}}async function s(){const e=document.getElementById("pmRoadmapPanel");if("none"===e.style.display)try{await t();const o=d(),l=n(o);console.log("[toggleRoadmap] projectId:",o,"proj:",l);let a="";if(l&&l.roadmapFile){console.log("[toggleRoadmap] Fetching project roadmap:",l.roadmapFile);a=(await fetch("/api/file-content?path="+encodeURIComponent(l.roadmapFile)).then(e=>e.json())).content||"(empty)"}else{console.log("[toggleRoadmap] Using default roadmap (no project selected or no roadmapFile)");a=(await fetch("/api/pm-loop/roadmap").then(e=>e.json())).content||"(empty)"}e.textContent=a,e.style.display="block"}catch(o){console.error("[toggleRoadmap] Error:",o),e.textContent="Could not load roadmap: "+o.message,e.style.display="block"}else e.style.display="none"}function m(){document.getElementById("pmStartBtn").onclick=()=>i(!1),document.getElementById("pmDryRunBtn").onclick=()=>i(!0),document.getElementById("pmStopBtn").onclick=p,document.getElementById("pmRoadmapBtn").onclick=s,t().then(()=>l()),document.getElementById("buildProjectPicker").addEventListener("change",()=>{o&&(clearInterval(o),o=null),l()})}export{m as i};