crewswarm 0.9.4 → 1.0.0

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 (64) hide show
  1. package/.env.example +8 -1
  2. package/README.md +58 -9
  3. package/apps/dashboard/README.md +49 -0
  4. package/apps/dashboard/dist/assets/{index-D-sRshvg.css → index-C5-vlIwl.css} +1 -1
  5. package/apps/dashboard/dist/assets/index-CSooN9fi.js +2 -0
  6. package/apps/dashboard/dist/assets/index-CSooN9fi.js.br +0 -0
  7. package/apps/dashboard/dist/assets/tab-spending-tab-DcXD5TQY.js +1 -0
  8. package/apps/dashboard/dist/assets/tab-spending-tab-DcXD5TQY.js.br +0 -0
  9. package/apps/dashboard/dist/assets/tab-testing-tab-Ea5K-rsb.js +1 -0
  10. package/apps/dashboard/dist/index.html +85 -7
  11. package/apps/dashboard/dist/index.html.br +0 -0
  12. package/contrib/openclaw-plugin/index.ts +20 -11
  13. package/install.sh +2 -2
  14. package/lib/autoharness/index.mjs +151 -1
  15. package/lib/chat/history.mjs +1 -1
  16. package/lib/contacts/identity-linker.mjs +24 -3
  17. package/lib/contacts/index.mjs +2 -1
  18. package/lib/crew-lead/chat-handler.mjs +56 -33
  19. package/lib/crew-lead/llm-caller.mjs +71 -14
  20. package/lib/crew-lead/prompts.mjs +4 -2
  21. package/lib/crew-lead/wave-dispatcher.mjs +53 -3
  22. package/lib/crew-lead/worktree.mjs +258 -0
  23. package/lib/crew-lead/ws-router.mjs +43 -0
  24. package/lib/engines/rt-envelope.mjs +4 -1
  25. package/lib/memory/relevance-scorer.mjs +199 -0
  26. package/lib/memory/shared-adapter.mjs +85 -19
  27. package/package.json +10 -3
  28. package/scripts/dashboard.mjs +398 -28
  29. package/scripts/health-check.mjs +70 -28
  30. package/scripts/install-docker.sh +1 -1
  31. package/scripts/restart-all-from-repo.sh +25 -21
  32. package/scripts/start.mjs +81 -26
  33. package/apps/dashboard/dist/assets/chat-core-uXb_C0GM.js.br +0 -0
  34. package/apps/dashboard/dist/assets/cli-process-CNZ_UBCt.js.br +0 -0
  35. package/apps/dashboard/dist/assets/components-BS9fQjE_.js.br +0 -0
  36. package/apps/dashboard/dist/assets/core-utils-CmOkXgzi.js.br +0 -0
  37. package/apps/dashboard/dist/assets/index-BeVllEj_.js +0 -2
  38. package/apps/dashboard/dist/assets/index-BeVllEj_.js.br +0 -0
  39. package/apps/dashboard/dist/assets/index-D-sRshvg.css.br +0 -0
  40. package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
  41. package/apps/dashboard/dist/assets/setup-wizard-CA0Or47w.js.br +0 -0
  42. package/apps/dashboard/dist/assets/tab-agents-tab-BgpIsjkw.js.br +0 -0
  43. package/apps/dashboard/dist/assets/tab-benchmarks-tab-BHjKCPm3.js.br +0 -0
  44. package/apps/dashboard/dist/assets/tab-comms-tab-kguqTIzD.js.br +0 -0
  45. package/apps/dashboard/dist/assets/tab-contacts-tab-DiOyMYth.js.br +0 -0
  46. package/apps/dashboard/dist/assets/tab-engines-tab-BsdZVvU0.js.br +0 -0
  47. package/apps/dashboard/dist/assets/tab-memory-tab-Cu6u13EQ.js.br +0 -0
  48. package/apps/dashboard/dist/assets/tab-models-tab-dNRgsTOO.js.br +0 -0
  49. package/apps/dashboard/dist/assets/tab-pm-loop-tab-DiAPTJXu.js.br +0 -0
  50. package/apps/dashboard/dist/assets/tab-projects-tab-SFH4E--a.js.br +0 -0
  51. package/apps/dashboard/dist/assets/tab-prompts-tab-DVkUNaJd.js.br +0 -0
  52. package/apps/dashboard/dist/assets/tab-services-tab-DU_LH3uG.js.br +0 -0
  53. package/apps/dashboard/dist/assets/tab-settings-tab-CuvH_Fj_.js.br +0 -0
  54. package/apps/dashboard/dist/assets/tab-skills-tab-DR7PJ7NB.js.br +0 -0
  55. package/apps/dashboard/dist/assets/tab-spending-tab-DEccQHnt.js +0 -1
  56. package/apps/dashboard/dist/assets/tab-spending-tab-DEccQHnt.js.br +0 -0
  57. package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BNrd88-r.js.br +0 -0
  58. package/apps/dashboard/dist/assets/tab-swarm-tab-B1AcjL1W.js.br +0 -0
  59. package/apps/dashboard/dist/assets/tab-testing-tab-CezZOZcJ.js +0 -1
  60. package/apps/dashboard/dist/assets/tab-testing-tab-CezZOZcJ.js.br +0 -0
  61. package/apps/dashboard/dist/assets/tab-usage-tab-BIOOnB-Y.js.br +0 -0
  62. package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
  63. package/apps/dashboard/dist/assets/tab-workflows-tab-B-soSy1k.js.br +0 -0
  64. package/apps/dashboard/dist/index.html.gz +0 -0
package/.env.example CHANGED
@@ -159,7 +159,14 @@
159
159
  # ── Ports ─────────────────────────────────────────────────────────────────────
160
160
  # CREW_LEAD_PORT=5010 # crew-lead HTTP API
161
161
  # SWARM_DASH_PORT=4319 # Dashboard web UI
162
- # WA_HTTP_PORT=3000 # WhatsApp bridge HTTP
162
+ # WA_HTTP_PORT=5015 # WhatsApp bridge HTTP
163
+ # STUDIO_PORT=3333 # Vibe IDE
164
+
165
+ # ── Runtime & Config ──────────────────────────────────────────────────────────
166
+ # CREWSWARM_DIR=$HOME/.crewswarm # Override config directory
167
+ # CREWSWARM_RT_AUTH_TOKEN= # RT bus auth token (auto-generated by install.sh)
168
+ # CREWSWARM_MAX_BRIDGES=10 # Max concurrent agent bridge processes
169
+ # CREWSWARM_BIND_HOST=127.0.0.1 # Host to bind all services to (use 0.0.0.0 for remote access)
163
170
 
164
171
  # ── Execution Engines ─────────────────────────────────────────────────────────
165
172
  # CREWSWARM_OPENCODE_ENABLED=off # Route coding agents through OpenCode
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # crewswarm
2
2
 
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.
3
+ **A multi-engine AI coding platform.** Switch between Claude Code, Cursor, Gemini, Codex, OpenCode, and crew-cli 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
6
  [![Release Check](https://img.shields.io/badge/release_check-required-blue)](https://github.com/crewswarm/crewswarm)
@@ -9,7 +9,7 @@
9
9
  [![Website](https://img.shields.io/badge/website-crewswarm.ai-blue)](https://crewswarm.ai)
10
10
  [![GitHub Sponsors](https://img.shields.io/github/sponsors/crewswarm?label=Sponsor)](https://github.com/sponsors/crewswarm)
11
11
 
12
- ![crewswarm Dashboard](website/dashboard-agents.webp)
12
+ ![crewswarm Demo](website/crewswarm-demo.gif)
13
13
 
14
14
  ---
15
15
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  **Rate limits are real.** Every $20/month AI coding plan has them. Claude, Cursor, Codex — you'll hit the wall mid-feature.
19
19
 
20
- crewswarm is the only tool where you seamlessly switch to another engine and keep your session context. Or pick the best CLI for each job:
20
+ crewswarm lets you switch engines without throwing away your working context. Or pick the best CLI for each job:
21
21
 
22
22
  | Engine | Best for | Key strength |
23
23
  |---|---|---|
@@ -26,7 +26,53 @@ crewswarm is the only tool where you seamlessly switch to another engine and kee
26
26
  | **Gemini CLI** | Research, SEO, free fallback | Free: 60 req/min, Google Search built in |
27
27
  | **Codex CLI** | Backend, fast iteration | Full sandbox, no approval prompts |
28
28
  | **OpenCode** | Provider flexibility | Any model (Groq/DeepSeek/Ollama) |
29
- | **crew-cli** | Orchestration, quality workflows | 20+ agents, sandbox, 3x parallel speedup |
29
+ | **crew-cli** | Execution engine, any model | 40+ models, 16 providers, sandbox, parallel workers |
30
+
31
+ ---
32
+
33
+ ## crew-cli: the execution engine
34
+
35
+ crew-cli is the built-in execution engine. It runs standalone or as one of crewswarm's 6 engines. Unlike other AI coding CLIs that lock you to one provider, crew-cli works with any model:
36
+
37
+ | Provider | Models | Driver |
38
+ |---|---|---|
39
+ | **OpenAI** | GPT-5.4, GPT-5.2, GPT-4.1, o3-mini, o4-mini | OpenAI API |
40
+ | **Anthropic** | Claude Opus/Sonnet/Haiku (API + OAuth) | Anthropic API + CCH |
41
+ | **Google** | Gemini 2.5 Flash, Gemini 3 Pro | Gemini API |
42
+ | **xAI** | Grok 4.20, Grok 4-1, Grok 3, grok-code-fast | OpenAI-compatible |
43
+ | **DeepSeek** | DeepSeek Chat, DeepSeek Reasoner | OpenAI-compatible |
44
+ | **Groq** | Llama 4 Scout, Kimi K2, Qwen3-32B, GPT-OSS | OpenAI-compatible |
45
+ | **Fireworks** | DeepSeek v3, GLM-5, Kimi K2.5, GPT-OSS | OpenAI-compatible |
46
+ | **Mistral** | Mistral Large, Codestral, Devstral | OpenAI-compatible |
47
+ | **Cerebras** | Qwen 3-235B, Llama 3.1 | OpenAI-compatible |
48
+ | **NVIDIA** | Llama 3.3-70B | OpenAI-compatible |
49
+ | **OpenCode/Zen** | 39 models (GPT-5.x, Claude, Gemini, GLM, Kimi, MiniMax, Qwen, Nemotron) | OpenAI-compatible |
50
+ | **OpenRouter** | 100+ models | OpenAI-compatible |
51
+ | **Ollama** | Any local model | OpenAI-compatible |
52
+
53
+ Three API formats, one engine. Bring your own keys, use OAuth from Claude Code / Codex / Gemini CLI, or run free models via Groq / Ollama / OpenRouter.
54
+
55
+ ### Benchmark: free models match Claude Opus
56
+
57
+ Single-model pipeline testing — same model handles routing, planning, execution, review, and fixing. All tests pass on 6 TypeScript coding tasks (bugfix, feature, refactor, multi-file).
58
+
59
+ | Model | Provider | Result | ~Cost/Task |
60
+ |---|---|---|---|
61
+ | Qwen 3.5 (397B) | Ollama cloud | **All tests pass** | FREE |
62
+ | GLM-5.1 | Ollama cloud | **All tests pass** | FREE |
63
+ | Claude Sonnet 4.6 | Anthropic OAuth | **All tests pass** | ~$0.06 |
64
+ | Claude Opus 4.6 | Anthropic OAuth | **All tests pass** | ~$0.07 |
65
+ | GPT-5.4 | OpenAI OAuth | **All tests pass** | ~$0.13 |
66
+
67
+ Two free local models (Qwen 3.5, GLM-5.1 via Ollama) pass every test that Claude Opus does. [Full results →](https://crewswarm.ai/benchmarks.html)
68
+
69
+ **What makes crew-cli different from other AI coding CLIs:**
70
+ - **Failure memory** — blocks repeated bad moves, forces new approaches
71
+ - **Verification-first** — won't declare success until proof is shown
72
+ - **Patch critic** — evaluates every edit for quality in real time
73
+ - **Parallel workers** — splits multi-file tasks into concurrent work units
74
+ - **Sandbox preview** — all changes staged before writing to disk
75
+ - **Smart delegation** — picks the right model tier for each subtask
30
76
 
31
77
  ---
32
78
 
@@ -85,11 +131,11 @@ Use Docker when you want stronger isolation, easier restarts, or a shared server
85
131
 
86
132
  1. **You write a requirement** — one sentence, one paragraph, or a full spec
87
133
  2. **crew-pm plans it** — breaks work into phases, assigns specialists
88
- 3. **Agents execute in parallel** — backend, frontend, tests built simultaneously (3x faster)
134
+ 3. **Agents execute in parallel** — backend, frontend, and tests can run simultaneously
89
135
  4. **Done. Files on disk.** — real files, real tests, real output
90
136
 
91
137
  ```
92
- Dashboard / Vibe IDE / crew-cli / Telegram / MCP
138
+ Dashboard / Vibe IDE / crew-cli / crewchat / Telegram / WhatsApp / OpenClaw / MCP
93
139
  |
94
140
  crew-lead (router)
95
141
  |
@@ -110,8 +156,11 @@ Dashboard / Vibe IDE / crew-cli / Telegram / MCP
110
156
 
111
157
  - **Dashboard** — web control plane at `localhost:4319` (agents, engines, models, build, sessions)
112
158
  - **Vibe IDE** — browser-based editor + terminal + chat at `localhost:3333`
113
- - **crew-cli** — terminal-first with 34+ built-in tools
159
+ - **crew-cli** — execution engine: 40+ models, 16 providers, 41 built-in tools
160
+ - **crewchat** — conversational interface for quick tasks
114
161
  - **Telegram** — chat with your crew from your phone
162
+ - **WhatsApp** — mobile messaging bridge
163
+ - **OpenClaw plugin** — use crewswarm as the engineering backend for OpenClaw desktop apps (`npm i crewswarm-openclaw-plugin`)
115
164
  - **MCP server** — plug crewswarm into any MCP-compatible editor
116
165
 
117
166
  ---
@@ -168,11 +217,11 @@ Or skip API keys entirely — use Claude Code, Cursor, or Gemini CLI with OAuth
168
217
  ## Commands
169
218
 
170
219
  ```bash
171
- crewswarm # Start all services
220
+ crewswarm # Start full stack: RT bus, crew-lead, bridges, then dashboard
172
221
  crewswarm pm-loop # Run autonomous PM loop
173
222
  npm run doctor # Preflight check
174
223
  npm run restart-all # Restart the stack
175
- npm test # 2,500+ tests, 100% passing
224
+ npm test # Run the core test suites
176
225
  npm run test:report # View test results summary
177
226
  crew exec "Build X" # Send task via CLI
178
227
  ```
@@ -0,0 +1,49 @@
1
+ # crewswarm-dashboard
2
+
3
+ Real-time control panel for CrewSwarm. Vanilla JS + Vite, no framework dependencies.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ cd apps/dashboard
9
+ npm install
10
+ npm run dev # http://localhost:5173
11
+ ```
12
+
13
+ ## Build
14
+
15
+ ```bash
16
+ npm run build # outputs to dist/
17
+ npm run preview # preview production build
18
+ ```
19
+
20
+ ## Structure
21
+
22
+ ```
23
+ src/
24
+ app.js # Main app entry, tab routing, SSE connections
25
+ styles.css # Global styles (dark theme)
26
+ chat/ # Chat tab (crew-lead conversation)
27
+ tabs/ # Tab modules (Build, Swarm, Agents, Engines, etc.)
28
+ components/ # Shared UI components
29
+ core/ # Core utilities (SSE, state, API client)
30
+ cli-process.js # CLI Process tab
31
+ setup-wizard.js # First-run setup wizard
32
+ orchestration-status.js # Pipeline status display
33
+ ```
34
+
35
+ ## Key tabs
36
+
37
+ - **Chat** -- Talk to crew-lead, dispatch tasks
38
+ - **Build** -- One-click build from a requirement
39
+ - **Swarm** -- Active sessions and agent activity
40
+ - **Agents** -- Configure sub-agents, models, permissions
41
+ - **Engines** -- Manage CLI engines (Claude Code, Codex, Gemini, Cursor)
42
+ - **RT Messages** -- Live message bus inspector
43
+ - **Services** -- Health status of all services
44
+
45
+ ## Notes
46
+
47
+ - Connects to crew-lead at `http://localhost:5010` by default
48
+ - All state comes from SSE streams and REST API -- no local state management
49
+ - Brotli-compressed `.br` files are pre-built for production serving
@@ -1 +1 @@
1
- :root{--bg: #060a10;--bg-0: #040810;--bg-1: #0d1420;--bg-2: #111827;--bg-card: #0d1420;--bg-card2: #111827;--bg-hover: #141e2e;--surface-2: #16202e;--border: rgba(255, 255, 255, .07);--border-hi: rgba(56, 189, 248, .35);--text: #f0f6ff;--text-1: #f0f6ff;--text-2: #a0b3cc;--text-3: #7a8a9f;--accent: #38bdf8;--accent2: #818cf8;--purple: #818cf8;--green: #34d399;--red: #f87171;--yellow: #fbbf24;--amber: #f59e0b;--green-hi: #22c55e;--red-hi: #ef4444;--sky: #38bdf8;--blue: #4a7ab5;--teal: #0f766e;--warning: #f59e0b;--radius: 10px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,sans-serif;background:var(--bg);color:var(--text);display:flex;height:100vh;overflow:hidden;font-size:14px;touch-action:manipulation}.skip-link{position:absolute;top:-40px;left:0;background:var(--accent);color:#000;padding:8px 16px;text-decoration:none;font-weight:600;border-radius:0 0 4px;z-index:9999}.skip-link:focus{top:0}*:focus-visible{outline:3px solid var(--accent);outline-offset:2px}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--accent);outline-offset:2px}.sidebar{width:216px;min-width:216px;background:var(--bg-card);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow-y:auto}.sidebar-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px;border-bottom:1px solid var(--border);text-decoration:none}.brand-icon{width:24px;height:24px;object-fit:contain;display:block}.brand-name{font-size:15px;font-weight:800;color:var(--text);letter-spacing:.06em;text-transform:uppercase}.brand-name span{color:var(--accent)}.sidebar-status{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--border)}.status-dot{width:7px;height:7px;border-radius:50%;background:var(--text-3);flex-shrink:0}.status-dot.online{background:var(--green);box-shadow:0 0 6px var(--green)}.status-dot.error{background:var(--red)}#status{font-size:12px;color:var(--text-2)}.nav-section{padding:12px 8px 4px}.nav-label{font-size:10px;font-weight:600;color:var(--text-3);letter-spacing:.08em;text-transform:uppercase;padding:0 8px 6px}.nav-item{display:flex;align-items:center;gap:9px;width:100%;padding:8px 10px;border-radius:7px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;text-align:left;transition:background .12s,color .12s;font-family:inherit}.stab{padding:7px 16px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;font-family:inherit;transition:color .12s,border-color .12s;white-space:nowrap}.stab:hover{color:var(--text-1)}.stab.active{color:var(--accent);border-bottom-color:var(--accent)}.nav-item:hover{background:var(--bg-hover);color:var(--text)}.nav-item.active{background:#38bdf81a;color:var(--accent)}.nav-item .nav-icon{font-size:15px;width:18px;text-align:center}.nav-badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:999px;min-width:18px;text-align:center}.nav-badge.hidden{display:none}.sidebar-bottom{margin-top:auto;padding:12px 8px;border-top:1px solid var(--border)}.main-wrap{flex:1;display:flex;flex-direction:column;overflow:hidden}.view{display:none;flex:1;overflow-y:auto;padding:24px}.view.active{display:block}.view-sessions{display:none;flex:1;overflow:hidden}.view-sessions.active{display:grid;grid-template-columns:34% 66%}.view-sessions>section{padding:16px;overflow-y:auto}.view-sessions>section+section{border-left:1px solid var(--border)}.msg-bar{padding:10px 16px;border-top:1px solid var(--border);background:var(--bg-card);display:flex;gap:8px;align-items:center;flex-shrink:0}.card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;margin-bottom:12px}.card-title{font-size:15px;font-weight:600;margin-bottom:4px}.status-badge{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;letter-spacing:.02em}.status-active,.status-running{background:#22c55e26;color:var(--green-hi);border:1px solid rgba(34,197,94,.3)}.status-stopped{background:#ef44441f;color:var(--red-hi);border:1px solid rgba(239,68,68,.25)}.meta{font-size:12px;color:var(--text-2)}.page-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:20px}.page-title{font-size:18px;font-weight:700;letter-spacing:-.3px}.page-sub{font-size:13px;color:var(--text-2);margin-top:3px}h3{font-size:14px;font-weight:600;margin-bottom:8px}.msg{border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;margin-bottom:8px;background:var(--bg-card)}.msg.u{border-left:3px solid var(--accent);background:#38bdf812;margin-left:40px}.msg.a{border-left:3px solid var(--green);background:#34d3990a}.dlq-item{border-left:3px solid var(--red)!important}.t{white-space:pre-wrap;font-size:13px;line-height:1.5;font-family:SF Mono,Fira Code,monospace}.chat-bubble{background:var(--surface-2);border-radius:10px;padding:12px 14px;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;max-width:85%;will-change:contents;contain:layout style paint}.chat-bubble.user{background:#38bdf81a;border:1px solid rgba(56,189,248,.2);margin-left:auto}.chat-bubble.assistant{background:var(--bg-card);border:1px solid var(--border)}#chatProjectTabs{scrollbar-width:thin;scrollbar-color:var(--border) transparent}#chatProjectTabs::-webkit-scrollbar{height:4px}#chatProjectTabs::-webkit-scrollbar-track{background:transparent}#chatProjectTabs::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}.project-tab{padding:6px 14px;border-radius:6px;font-size:12px;white-space:nowrap;cursor:pointer;border:none;background:#ffffff0a;color:var(--text-2);font-weight:500;transition:all .2s;font-family:inherit}.project-tab:hover{background:#ffffff14}.project-tab.active{background:var(--accent);color:var(--bg);font-weight:600}.row{padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;cursor:pointer;background:var(--bg-card);transition:border-color .12s,background .12s}.row:hover{background:var(--bg-hover)}.row.active{border-color:var(--accent);background:#38bdf80f}button{background:var(--accent);color:#000;border:none;border-radius:7px;padding:7px 14px;cursor:pointer;font-weight:600;font-size:13px;font-family:inherit;transition:opacity .12s}button:hover{opacity:.85}.btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border)}.btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.btn-green{background:var(--green);color:#000}.btn-sky{background:#0ea5e9;color:#000;border:1px solid #0ea5e9}.btn-sky:hover{background:var(--accent)}.btn-red{background:var(--red);color:#fff}.btn-yellow{background:var(--yellow);color:#000}.btn-purple{background:var(--accent2);color:#fff}.btn-muted{background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.reply-btn{font-size:11px;padding:3px 8px;background:var(--accent2);color:#fff;margin-left:8px}.replay-btn{font-size:11px;padding:3px 8px;background:var(--yellow);color:#000;margin-left:8px}.send-btn{background:var(--green);color:#000}.emoji-btn{width:46px;height:46px;font-size:22px;background:#ffffff0a;border:1px solid rgba(255,255,255,.1);border-radius:var(--radius);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .15s,background .15s;color:inherit}.emoji-btn:hover{border-color:var(--accent);background:#38bdf814}.emoji-picker-wrap{position:relative;flex-shrink:0}.emoji-picker-panel{display:none;position:absolute;top:50px;right:0;z-index:200;background:var(--bg-card);border:1px solid var(--border-hi);border-radius:var(--radius);padding:10px;box-shadow:0 8px 32px #00000080;width:260px}.emoji-picker-panel.open{display:block}.emoji-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:6px}.emoji-opt{font-size:22px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:6px;transition:background .1s}.emoji-opt:hover{background:#38bdf826}.file-row{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px;transition:border-color .15s}.file-row:hover{border-color:var(--accent)}.file-info{flex:1;min-width:0}.file-name{display:block;font-size:13px;color:var(--text);font-family:SF Mono,Fira Code,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-meta{font-size:11px;color:var(--text-2)}.file-actions{display:flex;gap:5px;flex-shrink:0}.file-btn{font-size:11px;padding:3px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-card2);color:var(--text-2);cursor:pointer;text-decoration:none;transition:all .15s;white-space:nowrap}.file-btn:hover{color:var(--text);border-color:var(--accent)}.file-btn-cursor{border-color:#6366f166;color:#818cf8}.file-btn-cursor:hover{background:#6366f126}.file-btn-opencode{border-color:#34d39966;color:#34d399}.file-btn-opencode:hover{background:#34d3991a}select,input[type=text],input[type=password],input[type=number],input[type=email],input:not([type]),textarea{background:var(--bg-1);color:var(--text-1);border:1px solid var(--border);border-radius:6px;padding:6px 10px;font-size:13px;font-family:inherit;outline:none;transition:border-color .15s,background .15s,box-shadow .15s;width:100%;box-sizing:border-box}select:focus,input:not([type]):focus,input[type=text]:focus,input[type=password]:focus,input[type=number]:focus,input[type=email]:focus,textarea:focus{border-color:var(--accent);background:#38bdf80a;box-shadow:0 0 0 3px #38bdf814}select{cursor:pointer}::placeholder{color:var(--text-3);opacity:1}input[type=text]{flex:1}textarea{resize:vertical;width:100%}input,textarea,select{user-select:text;-webkit-user-select:text;cursor:text}.inp-sm{padding:5px 8px!important;font-size:12px!important}.inp-xs{padding:3px 6px!important;font-size:12px!important;width:auto!important}.inp-mono{font-family:SF Mono,Fira Code,ui-monospace,monospace!important}.inp-flex{flex:1;width:auto!important}.notification{position:fixed;top:20px;right:20px;background:var(--green);color:#000;padding:12px 20px;border-radius:8px;box-shadow:0 4px 20px #0006;z-index:1000;animation:slideIn .25s ease;font-weight:600;font-size:13px}.notification.error{background:var(--red);color:#fff}.notification.warning{background:var(--amber);color:#000}@keyframes slideIn{0%{transform:translate(120%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes pulse{0%,to{opacity:.3;transform:scale(.85)}50%{opacity:1;transform:scale(1.15)}}.log-block{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:12px;font-family:SF Mono,Fira Code,monospace;font-size:12px;color:var(--accent);max-height:220px;overflow-y:auto;white-space:pre-wrap;line-height:1.5}.rm-textarea{width:100%;font-family:SF Mono,Fira Code,monospace;font-size:12px;background:var(--bg);color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:12px;line-height:1.6;resize:vertical;box-sizing:border-box}.log-block.green{color:var(--green);border-color:#34d39933}.log-block.mono{color:var(--text-2)}.provider-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-bottom:10px}.provider-header{display:flex;align-items:center;gap:12px;padding:13px 16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .12s}.provider-header:hover{background:var(--bg-hover)}.provider-badge{font-size:11px;padding:2px 8px;border-radius:999px;font-weight:600}.provider-body{display:none;padding:16px;border-top:1px solid var(--border);background:var(--bg)}.provider-body.open{display:block}.key-row{display:flex;gap:8px;align-items:center;margin-bottom:12px}.key-input{flex:1;font-family:SF Mono,Fira Code,ui-monospace,monospace}.model-tag{display:inline-block;background:var(--bg-card2);border:1px solid var(--border);border-radius:5px;padding:2px 8px;font-size:11px;margin:2px;font-family:SF Mono,monospace;color:var(--text-2)}.test-ok{color:var(--green);font-size:12px;margin-left:8px;font-weight:600}.test-err{color:var(--red);font-size:12px;margin-left:8px}.pm-badge{font-size:11px;padding:2px 10px;border-radius:999px;font-weight:600;margin-left:10px;background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.pm-badge.running{background:#34d3991a;color:var(--green);border-color:#34d3994d}.prog-bar{height:4px;background:var(--bg-card2);border-radius:2px;overflow:hidden;margin:8px 0}.prog-fill{height:100%;border-radius:2px;transition:width .3s}.divider{border:none;border-top:1px solid var(--border);margin:20px 0}.agent-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.agent-card-header{display:flex;align-items:center;gap:12px;padding:14px 16px}.agent-avatar{width:38px;height:38px;border-radius:10px;background:var(--bg-card2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}.agent-meta{flex:1;min-width:0}.agent-id{font-weight:700;font-size:14px}.agent-model{font-size:12px;color:var(--text-2);font-family:SF Mono,monospace;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-body{border-top:1px solid var(--border);padding:14px 16px;background:var(--bg);display:grid;gap:12px}.agent-row{display:grid;grid-template-columns:110px 1fr auto auto;gap:8px;align-items:center}.agent-row label{font-size:12px;color:var(--text-2);font-weight:500}.agent-badge{font-size:11px;padding:2px 8px;border-radius:999px;background:#38bdf81a;color:var(--accent);border:1px solid rgba(56,189,248,.2);font-weight:600}.agent-badge.online{background:#34d3991a;color:var(--green);border-color:#34d3994d}.field-label{font-size:11px;font-weight:600;color:var(--text-2);margin-bottom:5px;text-transform:uppercase;letter-spacing:.05em}.tool-profile-opt{cursor:pointer}.tool-profile-opt input[type=radio]{display:none}.tp-card{border:1px solid var(--border);border-radius:8px;padding:10px 12px;transition:border-color .12s,background .12s}.tool-profile-opt:hover .tp-card{border-color:var(--accent);background:var(--bg-hover)}.tool-profile-opt input:checked+.tp-card{border-color:var(--accent);background:#38bdf812}.tp-name{font-size:13px;font-weight:700;margin-bottom:4px;color:var(--text);font-family:SF Mono,monospace}.tp-desc{font-size:11px;color:var(--text-2);line-height:1.4}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}#rtView::-webkit-scrollbar{width:8px}#rtView::-webkit-scrollbar-track{background:var(--bg-card);border-radius:4px}#rtView::-webkit-scrollbar-thumb{background:var(--accent);border-radius:4px;opacity:.7}#rtView::-webkit-scrollbar-thumb:hover{background:var(--accent);opacity:1}#rtView{scrollbar-width:thin;scrollbar-color:var(--accent) var(--bg-card)}@media(max-width:1100px){body{flex-direction:column}.sidebar{width:100%!important;min-width:0!important;flex-direction:row;flex-wrap:wrap;padding:8px 12px;gap:4px;border-right:none;border-bottom:1px solid var(--border)}.sidebar .nav-item{padding:6px 10px;font-size:12px}.sidebar .nav-section{display:flex;flex-wrap:wrap;padding:0;gap:4px}.sidebar .nav-label,.sidebar .sidebar-bottom{display:none}.main-wrap{min-width:0}}@media(max-width:768px){.sidebar .nav-label{display:none}.sidebar .nav-item{padding:8px;min-width:36px;justify-content:center}#servicesGrid,#agentsList,#projectsList,#runSkillsGrid{grid-template-columns:1fr!important}.chat-input-row{flex-wrap:wrap;gap:6px}.chat-input-row button{height:44px}#chatInput{min-height:44px}.page-header{flex-direction:column;align-items:flex-start;gap:8px}.page-header .actions{flex-wrap:wrap}.container,.dashboard-grid,.view,.card{width:100%;max-width:100%;padding:1rem}img,video{max-width:100%;height:auto}button,a,.nav-item,input,select,textarea{min-height:44px}}@media(max-width:480px){body{font-size:13px}.card{padding:12px}.card-title{font-size:14px}.page-title{font-size:18px}.tab-bar{flex-wrap:wrap;gap:4px}.stab{padding:4px 10px;font-size:11px}button{min-height:44px;font-size:16px;padding:8px 16px}input,select,textarea{font-size:16px;min-height:44px}input:focus,select:focus,textarea:focus{font-size:16px}}.prompt-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;transition:all .2s}.prompt-card:hover{border-color:var(--border-hi);background:var(--bg-hover)}.prompt-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;gap:12px}.prompt-preview{font-size:12px;color:var(--text-2);line-height:1.5;font-family:SF Mono,Monaco,monospace;white-space:pre-wrap;word-break:break-word}.prompt-edit-btn{flex-shrink:0}.agent-info-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:16px}.agent-info-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.agent-info-header h4{margin:0;font-size:16px;font-weight:600}.agent-status{padding:4px 10px;border-radius:12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.agent-status.active{background:var(--green-hi);color:#000}.agent-status.idle{background:var(--bg-card2);color:var(--text-3)}.agent-info-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:13px;align-items:center}.detail-row .label{color:var(--text-3);font-weight:600}.detail-row .value{color:var(--text-1);font-family:SF Mono,Monaco,monospace;font-size:12px}#agentChatMessages{display:flex;flex-direction:column;gap:12px}.user-message,.agent-message{padding:12px 16px;border-radius:12px;max-width:75%;word-wrap:break-word}.user-message{background:var(--accent);color:#fff;align-self:flex-end;border-bottom-right-radius:4px}.agent-message{background:var(--bg-card);border:1px solid var(--border);align-self:flex-start;border-bottom-left-radius:4px}.message-header{display:flex;justify-content:space-between;margin-bottom:6px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;opacity:.8}.message-time{color:var(--text-3);font-size:10px;font-weight:400;text-transform:none;letter-spacing:0}.message-content{font-size:14px;line-height:1.6}.message-content code{background:#0000004d;padding:2px 6px;border-radius:4px;font-family:SF Mono,Monaco,monospace;font-size:13px}.message-content pre{background:#0006;padding:12px;border-radius:6px;overflow-x:auto;margin:8px 0;border:1px solid var(--border)}.message-content pre code{background:none;padding:0}.message-content a{color:var(--accent);text-decoration:none}.message-content a:hover{text-decoration:underline}.process-card{background:var(--bg-card);padding:12px;border-radius:8px;margin-bottom:8px}.process-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.process-cli{font-weight:600;font-family:SF Mono,Monaco,monospace;font-size:13px}.process-status{text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);letter-spacing:.05em}.process-details{font-size:12px;color:var(--text-2);line-height:1.6;font-family:SF Mono,Monaco,monospace}.empty-state{text-align:center;padding:60px 20px;color:var(--text-3);font-size:14px}.process-status-empty{padding:12px;text-align:center;color:var(--text-3);font-size:12px;font-style:italic}#workflowsLayout{display:grid;grid-template-columns:minmax(260px,340px) minmax(420px,1fr);gap:16px;align-items:start}@media(max-width:980px){#workflowsLayout{grid-template-columns:1fr}}.setup-wizard-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#040810eb;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);opacity:0;transition:opacity .26s ease}.setup-wizard-overlay.visible{opacity:1}.setup-wizard-overlay.dismissing{opacity:0}.setup-wizard-card{width:100%;max-width:520px;margin:0 16px;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:40px 36px 32px;box-shadow:0 0 0 1px #ffffff0a,0 24px 64px #00000080;transform:translateY(12px) scale(.98);opacity:0;transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s ease}.setup-wizard-card.visible{transform:translateY(0) scale(1);opacity:1}.setup-wizard-steps{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:32px}.setup-wizard-step{display:flex;flex-direction:column;align-items:center;gap:6px}.setup-wizard-step-dot{width:10px;height:10px;border-radius:50%;border:2px solid var(--text-3);background:transparent;padding:0;cursor:default;transition:background .2s ease,border-color .2s ease,box-shadow .2s ease}.setup-wizard-step-dot.active{border-color:var(--accent);background:var(--accent);box-shadow:0 0 8px #38bdf866}.setup-wizard-step-dot.completed{border-color:var(--green);background:var(--green)}.setup-wizard-step-label{font-size:11px;color:var(--text-3);font-weight:500;letter-spacing:.02em}.setup-wizard-step .active~.setup-wizard-step-label,.setup-wizard-step-dot.active+.setup-wizard-step-label{color:var(--accent)}.setup-wizard-step-dot.completed+.setup-wizard-step-label{color:var(--green)}.setup-wizard-step-line{width:48px;height:2px;background:var(--text-3);margin:0 12px 18px;border-radius:1px;transition:background .2s ease}.setup-wizard-step-line.completed{background:var(--green)}.setup-wizard-content{display:flex;flex-direction:column}.setup-wizard-hero{text-align:center;margin-bottom:28px}.setup-wizard-logo-ring{display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:16px;background:var(--bg-card2);border:1px solid var(--border);margin-bottom:20px}.setup-wizard-logo{width:36px;height:36px}.setup-wizard-title{font-size:24px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:8px;letter-spacing:-.02em}.setup-wizard-subtitle{font-size:15px;color:var(--text-2);line-height:1.5}.setup-wizard-checklist{display:flex;flex-direction:column;gap:10px;padding:16px 20px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;margin-bottom:28px}.setup-wizard-check-item{display:flex;align-items:center;gap:10px;font-size:14px;color:var(--text-2)}.setup-wizard-check-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:12px;flex-shrink:0}.setup-wizard-check-icon.done{background:#34d39926;color:var(--green);border:1px solid rgba(52,211,153,.3)}.setup-wizard-check-icon.pending{background:var(--bg-card);color:var(--text-3);border:1px solid var(--border);font-size:8px}.setup-wizard-section-header{margin-bottom:20px}.setup-wizard-section-title{font-size:20px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-section-desc{font-size:14px;color:var(--text-2);line-height:1.5}.setup-wizard-provider-list{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;max-height:360px;overflow-y:auto}.setup-wizard-provider-row{display:flex;flex-direction:column;gap:6px;padding:12px 14px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;transition:border-color .2s ease,background .2s ease}.setup-wizard-provider-row.has-key{border-color:#34d3994d;background:#34d3990a}.setup-wizard-provider-label{display:flex;align-items:center;gap:8px}.setup-wizard-provider-icon{font-size:16px;width:22px;text-align:center;flex-shrink:0}.setup-wizard-provider-name{font-size:14px;font-weight:600;color:var(--text)}.setup-wizard-provider-link{margin-left:auto;font-size:12px;color:var(--accent);text-decoration:none;opacity:.7;transition:opacity .15s ease}.setup-wizard-provider-link:hover{opacity:1;text-decoration:underline}.setup-wizard-provider-input-wrap{display:flex;align-items:center;gap:6px}.setup-wizard-provider-input{flex:1;background:var(--bg);border:1px solid var(--border);border-radius:7px;padding:8px 10px;color:var(--text);font-size:13px;font-family:inherit;outline:none;transition:border-color .2s ease}.setup-wizard-provider-input::placeholder{color:var(--text-3)}.setup-wizard-provider-input:focus{border-color:var(--accent)}.setup-wizard-toggle-vis{background:transparent;border:1px solid var(--border);border-radius:6px;padding:6px 8px;font-size:14px;cursor:pointer;color:var(--text-3);transition:color .15s ease}.setup-wizard-toggle-vis:hover{color:var(--text)}.setup-wizard-engine-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-bottom:16px}.setup-wizard-engine-card{background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:6px;transition:border-color .15s ease,background .15s ease}.setup-wizard-engine-card.available{border-color:#34d3994d;background:#34d39908}.setup-wizard-engine-card:not(.available){opacity:.7}.setup-wizard-engine-badge{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.setup-wizard-engine-badge.installed{color:var(--green, #34d399)}.setup-wizard-engine-badge.missing{color:var(--text-3, #666)}.setup-wizard-engine-title{font-size:15px;font-weight:600;color:var(--text)}.setup-wizard-engine-cmd{font-size:12px;color:var(--text-3);background:var(--bg-card);padding:2px 8px;border-radius:4px;display:inline-block;width:fit-content;font-family:var(--font-mono, monospace)}.setup-wizard-engine-desc{font-size:12px;color:var(--text-2);line-height:1.4;margin:4px 0 8px}.setup-wizard-engine-action{margin-top:auto;display:flex;align-items:center;gap:6px;font-size:12px}.setup-wizard-engine-auth-label{color:var(--text-3)}.setup-wizard-engine-auth-cmd{font-size:11px;color:var(--accent);background:#6366f11a;padding:3px 8px;border-radius:4px;font-family:var(--font-mono, monospace)}.setup-wizard-engine-key-note{font-size:12px}.setup-wizard-engine-key-note.key-ok{color:var(--green, #34d399)}.setup-wizard-engine-key-note.key-missing{color:var(--yellow, #fbbf24)}.setup-wizard-engine-install-btn{font-size:12px;color:var(--accent);text-decoration:none;font-weight:500;padding:4px 12px;border:1px solid var(--accent);border-radius:6px;transition:background .15s ease}.setup-wizard-engine-install-btn:hover{background:#6366f11a}.setup-wizard-engine-hint{font-size:13px;color:var(--text-2);text-align:center;margin:8px 0}.setup-wizard-provider-icon{font-size:16px;width:24px;text-align:center;flex-shrink:0}.setup-wizard-preset-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:24px}.setup-wizard-preset-card{display:flex;flex-direction:column;align-items:center;text-align:center;padding:20px 12px;background:var(--bg-card2);border:2px solid var(--border);border-radius:12px;cursor:pointer;transition:border-color .2s ease,background .2s ease,transform .15s ease}.setup-wizard-preset-card:hover{background:var(--bg-hover);transform:translateY(-1px)}.setup-wizard-preset-card.selected{border-color:var(--accent);background:#38bdf80f}.setup-wizard-preset-icon{font-size:28px;margin-bottom:10px;line-height:1}.setup-wizard-preset-label{font-size:15px;font-weight:700;color:var(--text);margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-preset-desc{font-size:12px;color:var(--text-2);line-height:1.4}.setup-wizard-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:8px}.setup-wizard-btn-primary{background:var(--accent);color:#000;border:none;border-radius:8px;padding:10px 24px;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;transition:opacity .15s ease,transform .1s ease}.setup-wizard-btn-primary:hover{opacity:.9}.setup-wizard-btn-primary:active{transform:scale(.98)}.setup-wizard-btn-primary:disabled{opacity:.4;cursor:not-allowed}.setup-wizard-btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:10px 20px;font-size:14px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease}.setup-wizard-btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.setup-wizard-error{padding:10px 14px;background:#f871711a;border:1px solid rgba(248,113,113,.25);border-radius:8px;color:var(--red);font-size:13px;margin-bottom:12px}.setup-wizard-error.hidden{display:none}@media(max-width:640px){.setup-wizard-card{padding:28px 20px 24px;margin:0 12px;border-radius:12px}.setup-wizard-engine-grid,.setup-wizard-preset-grid{grid-template-columns:1fr;gap:8px}.setup-wizard-preset-card{flex-direction:row;text-align:left;gap:12px;padding:14px 16px}.setup-wizard-preset-icon{font-size:22px;margin-bottom:0}.setup-wizard-preset-label{margin-bottom:2px}.setup-wizard-step-line{width:28px;margin:0 6px}.setup-wizard-actions{flex-direction:column-reverse}.setup-wizard-btn-primary,.setup-wizard-btn-ghost{width:100%;text-align:center}}.test-launch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;margin-bottom:20px}.test-launch-card{background:var(--bg-2, #1a1a2e);border:1px solid var(--border);border-left:3px solid;border-radius:8px;padding:12px 14px}.test-launch-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.test-launch-name{font-size:14px;font-weight:700}.test-launch-btn{font-size:11px;padding:3px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-2);color:var(--text-1);cursor:pointer;font-weight:600}.test-launch-btn:hover{background:#ffffff14}.test-launch-counts{display:flex;gap:12px;font-size:12px;color:var(--text-2)}.test-launch-files{font-weight:500}.test-launch-tests{color:var(--text-1);font-weight:600}.test-launch-total{background:#60a5fa0a}.test-suite-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px;margin-bottom:16px}.test-suite-card{background:var(--bg-2, #1a1a2e);border:1px solid var(--border);border-radius:10px;padding:16px}.test-suite-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.test-suite-name{font-size:15px;font-weight:700}.test-suite-stats{display:flex;gap:16px;font-size:13px;margin-bottom:8px}.test-suite-stats div{color:var(--text-2)}.test-suite-stats span{font-weight:600}.test-suite-meta{font-size:11px;color:var(--text-2);margin-bottom:10px}.test-summary-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.test-summary-status{font-size:13px;font-weight:700;letter-spacing:.5px;padding:4px 12px;border-radius:6px}.test-status-pass{background:#34d3991f;color:#34d399}.test-status-fail{background:#f871711f;color:#f87171}.test-summary-meta{font-size:12px;color:var(--text-2)}.test-meta-sep{margin:0 6px;opacity:.4}.test-summary-stats{display:flex;gap:32px;margin-bottom:14px}.test-stat{text-align:center}.test-stat-value{font-size:24px;font-weight:700;line-height:1.2}.test-stat-label{font-size:11px;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px}.test-color-pass{color:#34d399}.test-color-fail{color:#f87171}.test-color-skip{color:#fbbf24}.test-progress-bar{display:flex;height:6px;border-radius:3px;overflow:hidden;background:#ffffff0d}.test-progress-pass{background:#34d399}.test-progress-fail{background:#f87171}.test-progress-skip{background:#fbbf24}.test-actions{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}.test-section-title{font-size:13px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.4px;margin:20px 0 10px}.test-groups-table{width:100%;border-collapse:collapse;font-size:13px;margin-bottom:16px}.test-groups-table th{text-align:left;font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px;padding:8px 10px;border-bottom:1px solid var(--border)}.test-groups-table th.num,.test-groups-table td.num{text-align:right;font-variant-numeric:tabular-nums}.test-groups-table td{padding:6px 10px;border-bottom:1px solid rgba(255,255,255,.03)}.test-groups-table tbody tr:hover{background:#ffffff05}.test-row-fail{background:#f871710a}.test-cat-badge{font-size:11px;padding:2px 8px;border-radius:4px;font-weight:500}.test-cat-unit{background:#6366f126;color:#818cf8}.test-cat-integration{background:#34d39926;color:#34d399}.test-cat-e2e{background:#fbbf2426;color:#fbbf24}.test-cat-other{background:#94a3b826;color:#94a3b8}.test-failure-card{background:#f871710a;border:1px solid rgba(248,113,113,.15);border-radius:8px;padding:14px;margin-bottom:10px}.test-failure-name{font-weight:600;font-size:13px;margin-bottom:4px}.test-failure-file{font-size:11px;color:var(--text-2);margin-bottom:6px}.test-failure-class{font-size:10px;padding:2px 6px;border-radius:3px;background:#f871711f;color:#f87171;font-weight:500}.test-failure-error{font-size:11px;background:#0000004d;border-radius:6px;padding:10px;margin-top:8px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:var(--text-2);max-height:120px;overflow-y:auto}.test-failure-rerun{margin-top:8px}.test-failure-rerun code{font-size:10px;background:#ffffff0d;padding:4px 8px;border-radius:4px;display:inline-block;word-break:break-all}.test-progress-live{background:#60a5fa0f;border:1px solid rgba(96,165,250,.2);border-radius:10px;padding:14px 18px;margin-bottom:16px;animation:test-progress-pulse 2s ease-in-out infinite}.test-progress-done{animation:none;background:#34d3990f;border-color:#34d39933}@keyframes test-progress-pulse{0%,to{border-color:#60a5fa33}50%{border-color:#60a5fa80}}.test-progress-live-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.test-progress-live-status{font-weight:700;font-size:14px;color:var(--accent)}.test-progress-live-stats{display:flex;gap:16px;font-size:13px;font-weight:500;margin-bottom:4px}.test-progress-live-stats span{color:var(--text-2)}.test-progress-live-file{font-size:11px;color:var(--text-2);font-family:monospace;margin-top:4px}.test-skips-section{margin:12px 0}.test-skips-section[open] summary{margin-bottom:10px}.test-history-chart{display:flex;align-items:flex-end;gap:4px;padding:12px 0;min-height:90px}.test-history-bar{flex:1;display:flex;flex-direction:column;align-items:center;cursor:default;min-width:20px}.test-history-bar-inner{width:100%;max-width:28px;border-radius:3px;overflow:hidden;display:flex;flex-direction:column}.test-history-pass{background:#34d399}.test-history-fail{background:#f87171}.test-history-label{font-size:9px;color:var(--text-2);margin-top:4px;white-space:nowrap}.test-history-table{width:100%;border-collapse:collapse;font-size:12px;margin-top:12px}.test-history-table th{text-align:left;font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px;padding:6px 10px;border-bottom:1px solid var(--border)}.test-history-table th.num,.test-history-table td.num{text-align:right;font-variant-numeric:tabular-nums}.test-history-table td{padding:5px 10px;border-bottom:1px solid rgba(255,255,255,.03)}.test-history-table tbody tr:hover{background:#ffffff05}
1
+ :root{--bg: #060a10;--bg-0: #040810;--bg-1: #0d1420;--bg-2: #111827;--bg-card: #0d1420;--bg-card2: #111827;--bg-hover: #141e2e;--surface-2: #16202e;--border: rgba(255, 255, 255, .07);--border-hi: rgba(56, 189, 248, .35);--text: #f0f6ff;--text-1: #f0f6ff;--text-2: #a0b3cc;--text-3: #7a8a9f;--accent: #38bdf8;--accent2: #818cf8;--purple: #818cf8;--green: #34d399;--red: #f87171;--yellow: #fbbf24;--amber: #f59e0b;--green-hi: #22c55e;--red-hi: #ef4444;--sky: #38bdf8;--blue: #4a7ab5;--teal: #0f766e;--warning: #f59e0b;--radius: 10px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,sans-serif;background:var(--bg);color:var(--text);display:flex;height:100vh;overflow:hidden;font-size:14px;touch-action:manipulation}.skip-link{position:absolute;top:-40px;left:0;background:var(--accent);color:#000;padding:8px 16px;text-decoration:none;font-weight:600;border-radius:0 0 4px;z-index:9999}.skip-link:focus{top:0}*:focus-visible{outline:3px solid var(--accent);outline-offset:2px}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--accent);outline-offset:2px}.sidebar{width:216px;min-width:216px;background:var(--bg-card);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow-y:auto}.sidebar-brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px;border-bottom:1px solid var(--border);text-decoration:none}.brand-icon{width:24px;height:24px;object-fit:contain;display:block}.brand-name{font-size:15px;font-weight:800;color:var(--text);letter-spacing:.06em;text-transform:uppercase}.brand-name span{color:var(--accent)}.sidebar-status{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--border)}.status-dot{width:7px;height:7px;border-radius:50%;background:var(--text-3);flex-shrink:0}.status-dot.online{background:var(--green);box-shadow:0 0 6px var(--green)}.status-dot.error{background:var(--red)}#status{font-size:12px;color:var(--text-2)}.nav-section{padding:12px 8px 4px}.nav-label{font-size:10px;font-weight:600;color:var(--text-3);letter-spacing:.08em;text-transform:uppercase;padding:0 8px 6px}.nav-item{display:flex;align-items:center;gap:9px;width:100%;padding:8px 10px;border-radius:7px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;text-align:left;transition:background .12s,color .12s;font-family:inherit}.stab{padding:7px 16px;border:none;background:transparent;color:var(--text-2);font-size:13px;font-weight:500;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;font-family:inherit;transition:color .12s,border-color .12s;white-space:nowrap}.stab:hover{color:var(--text-1)}.stab.active{color:var(--accent);border-bottom-color:var(--accent)}.nav-item:hover{background:var(--bg-hover);color:var(--text)}.nav-item.active{background:#38bdf81a;color:var(--accent)}.nav-item .nav-icon{font-size:15px;width:18px;text-align:center}.nav-badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:999px;min-width:18px;text-align:center}.nav-badge.hidden{display:none}.sidebar-bottom{margin-top:auto;padding:12px 8px;border-top:1px solid var(--border)}.main-wrap{flex:1;display:flex;flex-direction:column;overflow:hidden}.view{display:none;flex:1;overflow-y:auto;padding:24px}.view.active{display:block}.view-sessions{display:none;flex:1;overflow:hidden}.view-sessions.active{display:grid;grid-template-columns:34% 66%}.view-sessions>section{padding:16px;overflow-y:auto}.view-sessions>section+section{border-left:1px solid var(--border)}.msg-bar{padding:10px 16px;border-top:1px solid var(--border);background:var(--bg-card);display:flex;gap:8px;align-items:center;flex-shrink:0}.card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;margin-bottom:12px}.card-title{font-size:15px;font-weight:600;margin-bottom:4px}.status-badge{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;padding:4px 10px;border-radius:20px;letter-spacing:.02em}.status-active,.status-running{background:#22c55e26;color:var(--green-hi);border:1px solid rgba(34,197,94,.3)}.status-stopped{background:#ef44441f;color:var(--red-hi);border:1px solid rgba(239,68,68,.25)}.meta{font-size:12px;color:var(--text-2)}.page-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:20px}.page-title{font-size:18px;font-weight:700;letter-spacing:-.3px}.page-sub{font-size:13px;color:var(--text-2);margin-top:3px}h3{font-size:14px;font-weight:600;margin-bottom:8px}.msg{border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;margin-bottom:8px;background:var(--bg-card)}.msg.u{border-left:3px solid var(--accent);background:#38bdf812;margin-left:40px}.msg.a{border-left:3px solid var(--green);background:#34d3990a}.dlq-item{border-left:3px solid var(--red)!important}.t{white-space:pre-wrap;font-size:13px;line-height:1.5;font-family:SF Mono,Fira Code,monospace}.chat-bubble{background:var(--surface-2);border-radius:10px;padding:12px 14px;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;max-width:85%;will-change:contents;contain:layout style paint}.chat-bubble.user{background:#38bdf81a;border:1px solid rgba(56,189,248,.2);margin-left:auto}.chat-bubble.assistant{background:var(--bg-card);border:1px solid var(--border)}#chatProjectTabs{scrollbar-width:thin;scrollbar-color:var(--border) transparent}#chatProjectTabs::-webkit-scrollbar{height:4px}#chatProjectTabs::-webkit-scrollbar-track{background:transparent}#chatProjectTabs::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}.project-tab{padding:6px 14px;border-radius:6px;font-size:12px;white-space:nowrap;cursor:pointer;border:none;background:#ffffff0a;color:var(--text-2);font-weight:500;transition:all .2s;font-family:inherit}.project-tab:hover{background:#ffffff14}.project-tab.active{background:var(--accent);color:var(--bg);font-weight:600}.row{padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;cursor:pointer;background:var(--bg-card);transition:border-color .12s,background .12s}.row:hover{background:var(--bg-hover)}.row.active{border-color:var(--accent);background:#38bdf80f}button{background:var(--accent);color:#000;border:none;border-radius:7px;padding:7px 14px;cursor:pointer;font-weight:600;font-size:13px;font-family:inherit;transition:opacity .12s}button:hover{opacity:.85}.btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border)}.btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.btn-green{background:var(--green);color:#000}.btn-sky{background:#0ea5e9;color:#000;border:1px solid #0ea5e9}.btn-sky:hover{background:var(--accent)}.btn-red{background:var(--red);color:#fff}.btn-yellow{background:var(--yellow);color:#000}.btn-purple{background:var(--accent2);color:#fff}.btn-muted{background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.reply-btn{font-size:11px;padding:3px 8px;background:var(--accent2);color:#fff;margin-left:8px}.replay-btn{font-size:11px;padding:3px 8px;background:var(--yellow);color:#000;margin-left:8px}.send-btn{background:var(--green);color:#000}.emoji-btn{width:46px;height:46px;font-size:22px;background:#ffffff0a;border:1px solid rgba(255,255,255,.1);border-radius:var(--radius);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .15s,background .15s;color:inherit}.emoji-btn:hover{border-color:var(--accent);background:#38bdf814}.emoji-picker-wrap{position:relative;flex-shrink:0}.emoji-picker-panel{display:none;position:absolute;top:50px;right:0;z-index:200;background:var(--bg-card);border:1px solid var(--border-hi);border-radius:var(--radius);padding:10px;box-shadow:0 8px 32px #00000080;width:260px}.emoji-picker-panel.open{display:block}.emoji-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:6px}.emoji-opt{font-size:22px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:6px;transition:background .1s}.emoji-opt:hover{background:#38bdf826}.file-row{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px;transition:border-color .15s}.file-row:hover{border-color:var(--accent)}.file-info{flex:1;min-width:0}.file-name{display:block;font-size:13px;color:var(--text);font-family:SF Mono,Fira Code,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-meta{font-size:11px;color:var(--text-2)}.file-actions{display:flex;gap:5px;flex-shrink:0}.file-btn{font-size:11px;padding:3px 8px;border-radius:4px;border:1px solid var(--border);background:var(--bg-card2);color:var(--text-2);cursor:pointer;text-decoration:none;transition:all .15s;white-space:nowrap}.file-btn:hover{color:var(--text);border-color:var(--accent)}.file-btn-cursor{border-color:#6366f166;color:#818cf8}.file-btn-cursor:hover{background:#6366f126}.file-btn-opencode{border-color:#34d39966;color:#34d399}.file-btn-opencode:hover{background:#34d3991a}select,input[type=text],input[type=password],input[type=number],input[type=email],input:not([type]),textarea{background:var(--bg-1);color:var(--text-1);border:1px solid var(--border);border-radius:6px;padding:6px 10px;font-size:13px;font-family:inherit;outline:none;transition:border-color .15s,background .15s,box-shadow .15s;width:100%;box-sizing:border-box}select:focus,input:not([type]):focus,input[type=text]:focus,input[type=password]:focus,input[type=number]:focus,input[type=email]:focus,textarea:focus{border-color:var(--accent);background:#38bdf80a;box-shadow:0 0 0 3px #38bdf814}select{cursor:pointer}::placeholder{color:var(--text-3);opacity:1}input[type=text]{flex:1}textarea{resize:vertical;width:100%}input,textarea,select{user-select:text;-webkit-user-select:text;cursor:text}.inp-sm{padding:5px 8px!important;font-size:12px!important}.inp-xs{padding:3px 6px!important;font-size:12px!important;width:auto!important}.inp-mono{font-family:SF Mono,Fira Code,ui-monospace,monospace!important}.inp-flex{flex:1;width:auto!important}.notification{position:fixed;top:20px;right:20px;background:var(--green);color:#000;padding:12px 20px;border-radius:8px;box-shadow:0 4px 20px #0006;z-index:1000;animation:slideIn .25s ease;font-weight:600;font-size:13px}.notification.error{background:var(--red);color:#fff}.notification.warning{background:var(--amber);color:#000}@keyframes slideIn{0%{transform:translate(120%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes pulse{0%,to{opacity:.3;transform:scale(.85)}50%{opacity:1;transform:scale(1.15)}}.log-block{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:12px;font-family:SF Mono,Fira Code,monospace;font-size:12px;color:var(--accent);max-height:220px;overflow-y:auto;white-space:pre-wrap;line-height:1.5}.rm-textarea{width:100%;font-family:SF Mono,Fira Code,monospace;font-size:12px;background:var(--bg);color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:12px;line-height:1.6;resize:vertical;box-sizing:border-box}.log-block.green{color:var(--green);border-color:#34d39933}.log-block.mono{color:var(--text-2)}.provider-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-bottom:10px}.provider-header{display:flex;align-items:center;gap:12px;padding:13px 16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .12s}.provider-header:hover{background:var(--bg-hover)}.provider-badge{font-size:11px;padding:2px 8px;border-radius:999px;font-weight:600}.provider-body{display:none;padding:16px;border-top:1px solid var(--border);background:var(--bg)}.provider-body.open{display:block}.key-row{display:flex;gap:8px;align-items:center;margin-bottom:12px}.key-input{flex:1;font-family:SF Mono,Fira Code,ui-monospace,monospace}.model-tag{display:inline-block;background:var(--bg-card2);border:1px solid var(--border);border-radius:5px;padding:2px 8px;font-size:11px;margin:2px;font-family:SF Mono,monospace;color:var(--text-2)}.test-ok{color:var(--green);font-size:12px;margin-left:8px;font-weight:600}.test-err{color:var(--red);font-size:12px;margin-left:8px}.pm-badge{font-size:11px;padding:2px 10px;border-radius:999px;font-weight:600;margin-left:10px;background:var(--bg-card2);color:var(--text-2);border:1px solid var(--border)}.pm-badge.running{background:#34d3991a;color:var(--green);border-color:#34d3994d}.prog-bar{height:4px;background:var(--bg-card2);border-radius:2px;overflow:hidden;margin:8px 0}.prog-fill{height:100%;border-radius:2px;transition:width .3s}.divider{border:none;border-top:1px solid var(--border);margin:20px 0}.agent-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.agent-card-header{display:flex;align-items:center;gap:12px;padding:14px 16px}.agent-avatar{width:38px;height:38px;border-radius:10px;background:var(--bg-card2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}.agent-meta{flex:1;min-width:0}.agent-id{font-weight:700;font-size:14px}.agent-model{font-size:12px;color:var(--text-2);font-family:SF Mono,monospace;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-body{border-top:1px solid var(--border);padding:14px 16px;background:var(--bg);display:grid;gap:12px}.agent-row{display:grid;grid-template-columns:110px 1fr auto auto;gap:8px;align-items:center}.agent-row label{font-size:12px;color:var(--text-2);font-weight:500}.agent-badge{font-size:11px;padding:2px 8px;border-radius:999px;background:#38bdf81a;color:var(--accent);border:1px solid rgba(56,189,248,.2);font-weight:600}.agent-badge.online{background:#34d3991a;color:var(--green);border-color:#34d3994d}.field-label{font-size:11px;font-weight:600;color:var(--text-2);margin-bottom:5px;text-transform:uppercase;letter-spacing:.05em}.tool-profile-opt{cursor:pointer}.tool-profile-opt input[type=radio]{display:none}.tp-card{border:1px solid var(--border);border-radius:8px;padding:10px 12px;transition:border-color .12s,background .12s}.tool-profile-opt:hover .tp-card{border-color:var(--accent);background:var(--bg-hover)}.tool-profile-opt input:checked+.tp-card{border-color:var(--accent);background:#38bdf812}.tp-name{font-size:13px;font-weight:700;margin-bottom:4px;color:var(--text);font-family:SF Mono,monospace}.tp-desc{font-size:11px;color:var(--text-2);line-height:1.4}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}#rtView::-webkit-scrollbar{width:8px}#rtView::-webkit-scrollbar-track{background:var(--bg-card);border-radius:4px}#rtView::-webkit-scrollbar-thumb{background:var(--accent);border-radius:4px;opacity:.7}#rtView::-webkit-scrollbar-thumb:hover{background:var(--accent);opacity:1}#rtView{scrollbar-width:thin;scrollbar-color:var(--accent) var(--bg-card)}@media(max-width:1100px){body{flex-direction:column}.sidebar{width:100%!important;min-width:0!important;flex-direction:row;flex-wrap:wrap;padding:8px 12px;gap:4px;border-right:none;border-bottom:1px solid var(--border)}.sidebar .nav-item{padding:6px 10px;font-size:12px}.sidebar .nav-section{display:flex;flex-wrap:wrap;padding:0;gap:4px}.sidebar .nav-label,.sidebar .sidebar-bottom{display:none}.main-wrap{min-width:0}}@media(max-width:768px){.sidebar .nav-label{display:none}.sidebar .nav-item{padding:8px;min-width:36px;justify-content:center}#servicesGrid,#agentsList,#projectsList,#runSkillsGrid{grid-template-columns:1fr!important}.chat-input-row{flex-wrap:wrap;gap:6px}.chat-input-row button{height:44px}#chatInput{min-height:44px}.page-header{flex-direction:column;align-items:flex-start;gap:8px}.page-header .actions{flex-wrap:wrap}.container,.dashboard-grid,.view,.card{width:100%;max-width:100%;padding:1rem}img,video{max-width:100%;height:auto}button,a,.nav-item,input,select,textarea{min-height:44px}}@media(max-width:480px){body{font-size:13px}.card{padding:12px}.card-title{font-size:14px}.page-title{font-size:18px}.tab-bar{flex-wrap:wrap;gap:4px}.stab{padding:4px 10px;font-size:11px}button{min-height:44px;font-size:16px;padding:8px 16px}input,select,textarea{font-size:16px;min-height:44px}input:focus,select:focus,textarea:focus{font-size:16px}}.prompt-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;transition:all .2s}.prompt-card:hover{border-color:var(--border-hi);background:var(--bg-hover)}.prompt-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;gap:12px}.prompt-preview{font-size:12px;color:var(--text-2);line-height:1.5;font-family:SF Mono,Monaco,monospace;white-space:pre-wrap;word-break:break-word}.prompt-edit-btn{flex-shrink:0}.agent-info-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:16px}.agent-info-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.agent-info-header h4{margin:0;font-size:16px;font-weight:600}.agent-status{padding:4px 10px;border-radius:12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.agent-status.active{background:var(--green-hi);color:#000}.agent-status.idle{background:var(--bg-card2);color:var(--text-3)}.agent-info-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:13px;align-items:center}.detail-row .label{color:var(--text-3);font-weight:600}.detail-row .value{color:var(--text-1);font-family:SF Mono,Monaco,monospace;font-size:12px}#agentChatMessages{display:flex;flex-direction:column;gap:12px}.user-message,.agent-message{padding:12px 16px;border-radius:12px;max-width:75%;word-wrap:break-word}.user-message{background:var(--accent);color:#fff;align-self:flex-end;border-bottom-right-radius:4px}.agent-message{background:var(--bg-card);border:1px solid var(--border);align-self:flex-start;border-bottom-left-radius:4px}.message-header{display:flex;justify-content:space-between;margin-bottom:6px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;opacity:.8}.message-time{color:var(--text-3);font-size:10px;font-weight:400;text-transform:none;letter-spacing:0}.message-content{font-size:14px;line-height:1.6}.message-content code{background:#0000004d;padding:2px 6px;border-radius:4px;font-family:SF Mono,Monaco,monospace;font-size:13px}.message-content pre{background:#0006;padding:12px;border-radius:6px;overflow-x:auto;margin:8px 0;border:1px solid var(--border)}.message-content pre code{background:none;padding:0}.message-content a{color:var(--accent);text-decoration:none}.message-content a:hover{text-decoration:underline}.process-card{background:var(--bg-card);padding:12px;border-radius:8px;margin-bottom:8px}.process-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.process-cli{font-weight:600;font-family:SF Mono,Monaco,monospace;font-size:13px}.process-status{text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);letter-spacing:.05em}.process-details{font-size:12px;color:var(--text-2);line-height:1.6;font-family:SF Mono,Monaco,monospace}.empty-state{text-align:center;padding:60px 20px;color:var(--text-3);font-size:14px}.process-status-empty{padding:12px;text-align:center;color:var(--text-3);font-size:12px;font-style:italic}#workflowsLayout{display:grid;grid-template-columns:minmax(260px,340px) minmax(420px,1fr);gap:16px;align-items:start}@media(max-width:980px){#workflowsLayout{grid-template-columns:1fr}}.setup-wizard-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#040810eb;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);opacity:0;transition:opacity .26s ease}.setup-wizard-overlay.visible{opacity:1}.setup-wizard-overlay.dismissing{opacity:0}.setup-wizard-card{width:100%;max-width:520px;margin:0 16px;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:40px 36px 32px;box-shadow:0 0 0 1px #ffffff0a,0 24px 64px #00000080;transform:translateY(12px) scale(.98);opacity:0;transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s ease}.setup-wizard-card.visible{transform:translateY(0) scale(1);opacity:1}.setup-wizard-steps{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:32px}.setup-wizard-step{display:flex;flex-direction:column;align-items:center;gap:6px}.setup-wizard-step-dot{width:10px;height:10px;border-radius:50%;border:2px solid var(--text-3);background:transparent;padding:0;cursor:default;transition:background .2s ease,border-color .2s ease,box-shadow .2s ease}.setup-wizard-step-dot.active{border-color:var(--accent);background:var(--accent);box-shadow:0 0 8px #38bdf866}.setup-wizard-step-dot.completed{border-color:var(--green);background:var(--green)}.setup-wizard-step-label{font-size:11px;color:var(--text-3);font-weight:500;letter-spacing:.02em}.setup-wizard-step .active~.setup-wizard-step-label,.setup-wizard-step-dot.active+.setup-wizard-step-label{color:var(--accent)}.setup-wizard-step-dot.completed+.setup-wizard-step-label{color:var(--green)}.setup-wizard-step-line{width:48px;height:2px;background:var(--text-3);margin:0 12px 18px;border-radius:1px;transition:background .2s ease}.setup-wizard-step-line.completed{background:var(--green)}.setup-wizard-content{display:flex;flex-direction:column}.setup-wizard-hero{text-align:center;margin-bottom:28px}.setup-wizard-logo-ring{display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:16px;background:var(--bg-card2);border:1px solid var(--border);margin-bottom:20px}.setup-wizard-logo{width:36px;height:36px}.setup-wizard-title{font-size:24px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:8px;letter-spacing:-.02em}.setup-wizard-subtitle{font-size:15px;color:var(--text-2);line-height:1.5}.setup-wizard-checklist{display:flex;flex-direction:column;gap:10px;padding:16px 20px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;margin-bottom:28px}.setup-wizard-check-item{display:flex;align-items:center;gap:10px;font-size:14px;color:var(--text-2)}.setup-wizard-check-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:12px;flex-shrink:0}.setup-wizard-check-icon.done{background:#34d39926;color:var(--green);border:1px solid rgba(52,211,153,.3)}.setup-wizard-check-icon.pending{background:var(--bg-card);color:var(--text-3);border:1px solid var(--border);font-size:8px}.setup-wizard-section-header{margin-bottom:20px}.setup-wizard-section-title{font-size:20px;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-section-desc{font-size:14px;color:var(--text-2);line-height:1.5}.setup-wizard-provider-list{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;max-height:360px;overflow-y:auto}.setup-wizard-provider-row{display:flex;flex-direction:column;gap:6px;padding:12px 14px;background:var(--bg-card2);border:1px solid var(--border);border-radius:10px;transition:border-color .2s ease,background .2s ease}.setup-wizard-provider-row.has-key{border-color:#34d3994d;background:#34d3990a}.setup-wizard-provider-label{display:flex;align-items:center;gap:8px}.setup-wizard-provider-icon{font-size:16px;width:22px;text-align:center;flex-shrink:0}.setup-wizard-provider-name{font-size:14px;font-weight:600;color:var(--text)}.setup-wizard-provider-link{margin-left:auto;font-size:12px;color:var(--accent);text-decoration:none;opacity:.7;transition:opacity .15s ease}.setup-wizard-provider-link:hover{opacity:1;text-decoration:underline}.setup-wizard-provider-input-wrap{display:flex;align-items:center;gap:6px}.setup-wizard-provider-input{flex:1;background:var(--bg);border:1px solid var(--border);border-radius:7px;padding:8px 10px;color:var(--text);font-size:13px;font-family:inherit;outline:none;transition:border-color .2s ease}.setup-wizard-provider-input::placeholder{color:var(--text-3)}.setup-wizard-provider-input:focus{border-color:var(--accent)}.setup-wizard-toggle-vis{background:transparent;border:1px solid var(--border);border-radius:6px;padding:6px 8px;font-size:14px;cursor:pointer;color:var(--text-3);transition:color .15s ease}.setup-wizard-toggle-vis:hover{color:var(--text)}.setup-wizard-engine-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-bottom:16px}.setup-wizard-engine-card{background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:6px;transition:border-color .15s ease,background .15s ease}.setup-wizard-engine-card.available{border-color:#34d3994d;background:#34d39908}.setup-wizard-engine-card:not(.available){opacity:.7}.setup-wizard-engine-badge{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.setup-wizard-engine-badge.installed{color:var(--green, #34d399)}.setup-wizard-engine-badge.missing{color:var(--text-3, #666)}.setup-wizard-engine-title{font-size:15px;font-weight:600;color:var(--text)}.setup-wizard-engine-cmd{font-size:12px;color:var(--text-3);background:var(--bg-card);padding:2px 8px;border-radius:4px;display:inline-block;width:fit-content;font-family:var(--font-mono, monospace)}.setup-wizard-engine-desc{font-size:12px;color:var(--text-2);line-height:1.4;margin:4px 0 8px}.setup-wizard-engine-action{margin-top:auto;display:flex;align-items:center;gap:6px;font-size:12px}.setup-wizard-engine-auth-label{color:var(--text-3)}.setup-wizard-engine-auth-cmd{font-size:11px;color:var(--accent);background:#6366f11a;padding:3px 8px;border-radius:4px;font-family:var(--font-mono, monospace)}.setup-wizard-engine-key-note{font-size:12px}.setup-wizard-engine-key-note.key-ok{color:var(--green, #34d399)}.setup-wizard-engine-key-note.key-missing{color:var(--yellow, #fbbf24)}.setup-wizard-engine-install-btn{font-size:12px;color:var(--accent);text-decoration:none;font-weight:500;padding:4px 12px;border:1px solid var(--accent);border-radius:6px;transition:background .15s ease}.setup-wizard-engine-install-btn:hover{background:#6366f11a}.setup-wizard-engine-hint{font-size:13px;color:var(--text-2);text-align:center;margin:8px 0}.setup-wizard-provider-icon{font-size:16px;width:24px;text-align:center;flex-shrink:0}.setup-wizard-preset-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:24px}.setup-wizard-preset-card{display:flex;flex-direction:column;align-items:center;text-align:center;padding:20px 12px;background:var(--bg-card2);border:2px solid var(--border);border-radius:12px;cursor:pointer;transition:border-color .2s ease,background .2s ease,transform .15s ease}.setup-wizard-preset-card:hover{background:var(--bg-hover);transform:translateY(-1px)}.setup-wizard-preset-card.selected{border-color:var(--accent);background:#38bdf80f}.setup-wizard-preset-icon{font-size:28px;margin-bottom:10px;line-height:1}.setup-wizard-preset-label{font-size:15px;font-weight:700;color:var(--text);margin-bottom:6px;letter-spacing:-.01em}.setup-wizard-preset-desc{font-size:12px;color:var(--text-2);line-height:1.4}.setup-wizard-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:8px}.setup-wizard-btn-primary{background:var(--accent);color:#000;border:none;border-radius:8px;padding:10px 24px;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;transition:opacity .15s ease,transform .1s ease}.setup-wizard-btn-primary:hover{opacity:.9}.setup-wizard-btn-primary:active{transform:scale(.98)}.setup-wizard-btn-primary:disabled{opacity:.4;cursor:not-allowed}.setup-wizard-btn-ghost{background:transparent;color:var(--text-2);border:1px solid var(--border);border-radius:8px;padding:10px 20px;font-size:14px;font-weight:500;font-family:inherit;cursor:pointer;transition:background .15s ease,color .15s ease}.setup-wizard-btn-ghost:hover{background:var(--bg-hover);color:var(--text)}.setup-wizard-error{padding:10px 14px;background:#f871711a;border:1px solid rgba(248,113,113,.25);border-radius:8px;color:var(--red);font-size:13px;margin-bottom:12px}.setup-wizard-error.hidden{display:none}@media(max-width:640px){.setup-wizard-card{padding:28px 20px 24px;margin:0 12px;border-radius:12px}.setup-wizard-engine-grid,.setup-wizard-preset-grid{grid-template-columns:1fr;gap:8px}.setup-wizard-preset-card{flex-direction:row;text-align:left;gap:12px;padding:14px 16px}.setup-wizard-preset-icon{font-size:22px;margin-bottom:0}.setup-wizard-preset-label{margin-bottom:2px}.setup-wizard-step-line{width:28px;margin:0 6px}.setup-wizard-actions{flex-direction:column-reverse}.setup-wizard-btn-primary,.setup-wizard-btn-ghost{width:100%;text-align:center}}.test-launch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;margin-bottom:20px}.test-launch-card{background:var(--bg-2, #1a1a2e);border:1px solid var(--border);border-left:3px solid;border-radius:8px;padding:12px 14px}.test-launch-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.test-launch-name{font-size:14px;font-weight:700}.test-launch-btn{font-size:11px;padding:3px 10px;border-radius:5px;border:1px solid var(--border);background:var(--bg-2);color:var(--text-1);cursor:pointer;font-weight:600}.test-launch-btn:hover{background:#ffffff14}.test-stop-btn{font-size:11px;padding:3px 10px;border-radius:5px;border:1px solid #ef4444;background:#ef444426;color:#ef4444;cursor:pointer;font-weight:600}.test-stop-btn:hover{background:#ef44444d}.test-launch-counts{display:flex;gap:12px;font-size:12px;color:var(--text-2)}.test-launch-files{font-weight:500}.test-launch-tests{color:var(--text-1);font-weight:600}.test-launch-total{background:#60a5fa0a}.test-suite-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px;margin-bottom:16px}.test-suite-card{background:var(--bg-2, #1a1a2e);border:1px solid var(--border);border-radius:10px;padding:16px}.test-suite-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.test-suite-name{font-size:15px;font-weight:700}.test-suite-stats{display:flex;gap:16px;font-size:13px;margin-bottom:8px}.test-suite-stats div{color:var(--text-2)}.test-suite-stats span{font-weight:600}.test-suite-meta{font-size:11px;color:var(--text-2);margin-bottom:10px}.test-summary-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.test-summary-status{font-size:13px;font-weight:700;letter-spacing:.5px;padding:4px 12px;border-radius:6px}.test-status-pass{background:#34d3991f;color:#34d399}.test-status-fail{background:#f871711f;color:#f87171}.test-summary-meta{font-size:12px;color:var(--text-2)}.test-meta-sep{margin:0 6px;opacity:.4}.test-summary-stats{display:flex;gap:32px;margin-bottom:14px}.test-stat{text-align:center}.test-stat-value{font-size:24px;font-weight:700;line-height:1.2}.test-stat-label{font-size:11px;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px}.test-color-pass{color:#34d399}.test-color-fail{color:#f87171}.test-color-skip{color:#fbbf24}.test-progress-bar{display:flex;height:6px;border-radius:3px;overflow:hidden;background:#ffffff0d}.test-progress-pass{background:#34d399}.test-progress-fail{background:#f87171}.test-progress-skip{background:#fbbf24}.test-actions{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}.test-section-title{font-size:13px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.4px;margin:20px 0 10px}.test-groups-table{width:100%;border-collapse:collapse;font-size:13px;margin-bottom:16px}.test-groups-table th{text-align:left;font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px;padding:8px 10px;border-bottom:1px solid var(--border)}.test-groups-table th.num,.test-groups-table td.num{text-align:right;font-variant-numeric:tabular-nums}.test-groups-table td{padding:6px 10px;border-bottom:1px solid rgba(255,255,255,.03)}.test-groups-table tbody tr:hover{background:#ffffff05}.test-row-fail{background:#f871710a}.test-cat-badge{font-size:11px;padding:2px 8px;border-radius:4px;font-weight:500}.test-cat-unit{background:#6366f126;color:#818cf8}.test-cat-integration{background:#34d39926;color:#34d399}.test-cat-e2e{background:#fbbf2426;color:#fbbf24}.test-cat-other{background:#94a3b826;color:#94a3b8}.test-failure-card{background:#f871710a;border:1px solid rgba(248,113,113,.15);border-radius:8px;padding:14px;margin-bottom:10px}.test-failure-name{font-weight:600;font-size:13px;margin-bottom:4px}.test-failure-file{font-size:11px;color:var(--text-2);margin-bottom:6px}.test-failure-class{font-size:10px;padding:2px 6px;border-radius:3px;background:#f871711f;color:#f87171;font-weight:500}.test-failure-error{font-size:11px;background:#0000004d;border-radius:6px;padding:10px;margin-top:8px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:var(--text-2);max-height:120px;overflow-y:auto}.test-failure-rerun{margin-top:8px}.test-failure-rerun code{font-size:10px;background:#ffffff0d;padding:4px 8px;border-radius:4px;display:inline-block;word-break:break-all}.test-progress-live{background:#60a5fa0f;border:1px solid rgba(96,165,250,.2);border-radius:10px;padding:14px 18px;margin-bottom:16px;animation:test-progress-pulse 2s ease-in-out infinite}.test-progress-done{animation:none;background:#34d3990f;border-color:#34d39933}@keyframes test-progress-pulse{0%,to{border-color:#60a5fa33}50%{border-color:#60a5fa80}}.test-progress-live-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.test-progress-live-status{font-weight:700;font-size:14px;color:var(--accent)}.test-progress-live-stats{display:flex;gap:16px;font-size:13px;font-weight:500;margin-bottom:4px}.test-progress-live-stats span{color:var(--text-2)}.test-progress-live-file{font-size:11px;color:var(--text-2);font-family:monospace;margin-top:4px}.test-skips-section{margin:12px 0}.test-skips-section[open] summary{margin-bottom:10px}.test-history-chart{display:flex;align-items:flex-end;gap:4px;padding:12px 0;min-height:90px}.test-history-bar{flex:1;display:flex;flex-direction:column;align-items:center;cursor:default;min-width:20px}.test-history-bar-inner{width:100%;max-width:28px;border-radius:3px;overflow:hidden;display:flex;flex-direction:column}.test-history-pass{background:#34d399}.test-history-fail{background:#f87171}.test-history-label{font-size:9px;color:var(--text-2);margin-top:4px;white-space:nowrap}.test-history-table{width:100%;border-collapse:collapse;font-size:12px;margin-top:12px}.test-history-table th{text-align:left;font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.3px;padding:6px 10px;border-bottom:1px solid var(--border)}.test-history-table th.num,.test-history-table td.num{text-align:right;font-variant-numeric:tabular-nums}.test-history-table td{padding:5px 10px;border-bottom:1px solid rgba(255,255,255,.03)}.test-history-table tbody tr:hover{background:#ffffff05}.test-file-list{margin-top:8px;border-top:1px solid var(--border);padding-top:6px;max-height:180px;overflow-y:auto}.test-file-row{display:flex;align-items:center;gap:6px;padding:3px 0;font-size:11px}.test-file-dot{font-size:8px;flex-shrink:0}.test-file-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-2)}.test-file-counts{color:var(--text-3);font-size:10px;white-space:nowrap}.test-file-run-btn{background:#6366f126;color:#818cf8;border:1px solid rgba(99,102,241,.3);border-radius:4px;padding:1px 6px;font-size:9px;cursor:pointer;flex-shrink:0;transition:background .15s}.test-file-run-btn:hover{background:#6366f14d}.test-stale-badge{background:#fbbf2426;color:#fbbf24;border:1px solid rgba(251,191,36,.3);border-radius:3px;font-size:9px;padding:1px 5px;white-space:nowrap;flex-shrink:0}.test-stream-panel{margin:12px 0;background:#0a0f1a;border:1px solid var(--border);border-radius:8px;overflow:hidden}.test-stream-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:#0d1420;border-bottom:1px solid var(--border);font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.5px}.test-stream-close{background:none;border:none;color:var(--text-3);cursor:pointer;font-size:13px;padding:0 4px}.test-stream-close:hover{color:var(--text-1)}.test-stream-pre{margin:0;padding:12px;font-size:11px;font-family:SF Mono,Fira Code,Fira Mono,monospace;color:#a8d8a8;max-height:300px;overflow-y:auto;white-space:pre-wrap;word-break:break-all;line-height:1.5}.test-failure-expandable{cursor:default}.test-failure-header{display:flex;align-items:flex-start;gap:8px;cursor:pointer;padding:8px 12px;margin:-8px -12px;border-radius:4px;transition:background .1s}.test-failure-header:hover{background:#ffffff0a}.test-failure-toggle{color:var(--text-3);font-size:10px;flex-shrink:0;margin-top:2px}.test-failure-file-inline{color:var(--text-3);font-size:10px;margin-left:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}.test-failure-detail{margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}.test-failure-stack{background:#0a0f1a;border:1px solid var(--border);border-radius:4px;padding:8px 12px;font-size:10px;color:#fca5a5;overflow-x:auto;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;margin-top:6px}.test-failure-actions{display:flex;flex-direction:column;gap:6px;margin-top:8px}.test-failure-link{color:var(--accent);font-size:11px;text-decoration:none}.test-failure-link:hover{text-decoration:underline}.test-copy-btn{background:#6366f126;color:#818cf8;border:1px solid rgba(99,102,241,.3);border-radius:4px;padding:2px 8px;font-size:10px;cursor:pointer;margin-left:8px;transition:background .15s}.test-copy-btn:hover{background:#6366f14d}.test-failure-screenshot{margin-top:8px}.test-screenshot-thumb{max-width:200px;max-height:140px;border:1px solid var(--border);border-radius:4px;cursor:zoom-in;display:block;transition:max-width .2s,max-height .2s;object-fit:contain}.test-screenshot-thumb.test-screenshot-expanded{max-width:100%;max-height:600px;cursor:zoom-out}.test-coverage-grid{display:flex;flex-wrap:wrap;gap:3px;margin:10px 0}.test-coverage-block{width:14px;height:14px;border-radius:2px;cursor:pointer;transition:transform .1s,opacity .1s}.test-coverage-block:hover{transform:scale(1.3);opacity:.9}.test-coverage-covered{background:#22c55e}.test-coverage-uncovered{background:#ef4444;opacity:.7}.test-coverage-legend{display:flex;gap:16px;font-size:11px;color:var(--text-2);margin-top:4px}.test-coverage-dot{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:4px;vertical-align:middle}.test-coverage-dot-green{background:#22c55e}.test-coverage-dot-red{background:#ef4444}.test-chart-wrap{background:#ffffff05;border:1px solid var(--border);border-radius:8px;padding:12px;overflow-x:auto}.test-chart-legend{font-size:11px;font-weight:400;color:var(--text-2);margin-left:12px;text-transform:none;letter-spacing:0}.test-chart-legend span{margin-right:10px}
@@ -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,g as o,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-CNZ_UBCt.js";import{i as w}from"./chat-core-uXb_C0GM.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 O,s as R,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 ae,w as oe,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{i as pe,s as me,c as ue,t as ge,r as he,l as ve,a as fe,b as ye}from"./tab-testing-tab-Ea5K-rsb.js";import{s as we,a as be,l as xe,c as Ce,b as ke,i as Ee,t as Ie,d as Te,f as Be,r as Se,e as je,g as Ae,u as Pe}from"./tab-skills-tab-DR7PJ7NB.js";import{s as Le,i as Me,a as _e,l as Ne}from"./tab-contacts-tab-DiOyMYth.js";import{i as Oe,t as Re,l as Fe,d as He}from"./tab-engines-tab-BsdZVvU0.js";import{s as De,a as ze,b as Ge,c as $e,t as Ve,d as qe,r as Ke,i as Ue}from"./tab-swarm-tab-B1AcjL1W.js";import{i as We,s as Je,t as Qe,a as Ye,b as Xe,c as Ze,d as et,e as tt,f as nt,g as at,h as ot,j as st,k as it,l as rt,m as lt}from"./tab-models-tab-dNRgsTOO.js";import{s as ct,a as dt,b as pt,t as mt,c as ut,d as gt,e as ht,f as vt,g as ft,h as yt,i as wt,j as bt,k as xt,l as Ct,m as kt,u as Et,n as It,o as Tt,p as Bt,q as St,r as jt,v as At,w as Pt,x as Lt,y as Mt,z as _t,A as Nt,B as Ot,C as Rt,D as Ft,E as Ht,F as Dt,G as zt,H as Gt,I as $t,J as Vt}from"./tab-settings-tab-CuvH_Fj_.js";import{i as qt,s as Kt,l as Ut,a as Wt,b as Jt,c as Qt,d as Yt,e as Xt,f as Zt,g as en,h as tn,r as nn,j as an}from"./tab-comms-tab-kguqTIzD.js";import{i as on,p as sn,r as rn,c as ln,a as cn,b as dn,e as pn,d as mn,l as un,o as gn,f as hn,h as vn,j as fn,k as yn,m as wn,n as bn,q as xn,t as Cn,v as kn,w as En}from"./tab-projects-tab-SFH4E--a.js";import{a as In,r as Tn,c as Bn,b as Sn,l as jn,d as An}from"./tab-usage-tab-BIOOnB-Y.js";import{s as Pn,r as Ln,l as Mn,a as _n,b as Nn,c as On}from"./tab-spending-tab-DcXD5TQY.js";import{i as Rn}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 Fn={};let Hn=null;async function Dn(){return Hn||(Hn=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 a=document.querySelector("meta[property=csp-nonce]"),o=(null==a?void 0:a.nonce)||(null==a?void 0:a.getAttribute("nonce"));n=e(t.map(e=>{if((e=function(e){return"/"+e}(e))in Fn)return;Fn[e]=!0;const t=e.endsWith(".css"),n=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${n}`))return;const a=document.createElement("link");return a.rel=t?"stylesheet":"modulepreload",t||(a.as="script"),a.crossOrigin="",a.href=e,o&&a.setAttribute("nonce",o),document.head.appendChild(a),t?new Promise((t,n)=>{a.addEventListener("load",t),a.addEventListener("error",()=>n(new Error(`Unable to preload CSS for ${e}`)))}):void 0}))}function a(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&&a(e.reason);return e().catch(a)})}(()=>import("./tab-benchmarks-tab-BHjKCPm3.js"),__vite__mapDeps([0,1]))),Hn}async function zn(){try{const e=document.getElementById("statusDot");document.getElementById("status").textContent="online",e.className="status-dot online",await Bn();const t=await o("/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 Gn(){await zn()}function $n(e){document.querySelectorAll(".nav-item").forEach(e=>e.classList.remove("active"));const t=document.getElementById(e);t&&t.classList.add("active")}function Vn(){u(a.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 qn(e){const t=document.getElementById(e),n=encodeURIComponent((null==t?void 0:t.value)||window._crewHome||""),a=await o("/api/pick-folder?default="+n).catch(()=>null);(null==a?void 0:a.path)&&t&&(t.value=a.path)}function Kn(){const e=(location.hash||"#chat").slice(1),t=(e.split("?")[0]||"chat").split("/");return{view:t[0]||"chat",subtab:t[1],raw:e}}function Un(){return Kn().view}function Wn(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 Jn(){try{const e=await o("/api/ui/active-project");return String((null==e?void 0:e.projectId)||"").trim()||"general"}catch{return"general"}}async function Qn(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 Yn(){Vn(),document.getElementById("chatView").classList.add("active"),$n("navChat"),a.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 pa();const n=t&&"true"===t.dataset.historyLoaded&&t.children.length>0;try{const e=(await o("/api/projects")).projects||[];a.projectsData={},e.forEach(e=>{a.projectsData[e.id]=e}),s(),sn(e)}catch(c){console.warn("Failed to refresh projects dropdown:",c)}const i=new URLSearchParams(window.location.hash.replace(/^#chat\?/,"")).get("project");if(i)a.chatActiveProjectId=i;else{const e=await Jn();try{a.chatActiveProjectId=e||localStorage.getItem("crewswarm_chat_active_project_id")||"general"}catch{a.chatActiveProjectId=e||"general"}}window.location.hash.includes("?project=")||Wn(a.chatActiveProjectId),console.log("🔵 [INIT] Active project from URL:",a.chatActiveProjectId);const r=document.getElementById("chatProjectTabs");r&&Array.from(r.children).forEach(e=>{e.dataset.projectId===a.chatActiveProjectId?e.classList.add("active"):e.classList.remove("active")});const l=document.getElementById("chatProjectSelect");l&&a.chatActiveProjectId&&l.querySelector('option[value="'+a.chatActiveProjectId+'"]')&&(l.value=a.chatActiveProjectId),Qn(a.chatActiveProjectId),Bn(),ta(),async function(){try{const e=((await o("/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 da()}function Xn(){Vn(),document.getElementById("filesView").classList.add("active"),$n("navFiles"),a.activeTab="files",s(),Ea()}function Zn(){return"owner"}P({hideAllViews:Vn,setNavActive:$n}),O({hideAllViews:Vn,setNavActive:$n,refreshAgents:F}),ce({hideAllViews:Vn,setNavActive:$n}),Ue({hideAllViews:Vn,setNavActive:$n}),k(),E({hideAllViews:Vn,setNavActive:$n}),pe({hideAllViews:Vn,setNavActive:$n});let ea=null;function ta(){if(ea)return;const e=`http://${window.location.hostname||"127.0.0.1"}:5010/events`;console.log("[crewswarm] Starting EventSource listener for",e),ea=new EventSource(e);const t="undefined"!=typeof localStorage&&"1"===localStorage.getItem("crewswarm_debug_sse");ea.onmessage=e=>{if(e.data)try{const o=JSON.parse(e.data),s=e=>e&&"general"!==e?e:"general",r="owner";t&&console.log("[crewswarm] SSE:",o.type,e.data.slice(0,120));const l=document.getElementById("chatMessages");if(C(o))return;if("chat_stream"===o.type&&o.sessionId===r){const e=s(o.projectId);if(s(a.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 a=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"};n.textContent=a.emoji+" "+a.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||"")+o.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"===o.type&&o.draftId){const e=document.querySelector('[data-draft-id="'+o.draftId+'"]');return void(e&&e.remove())}if("context_warning"===o.type&&"owner"===o.sessionId){const e=document.getElementById("contextWarningBanner");e&&e.remove();const t=document.createElement("div");t.id="contextWarningBanner";const n="critical"===o.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;">${o.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 a=document.getElementById("chatMessages");return void(a&&(a.appendChild(t),a.scrollTop=a.scrollHeight))}if("chat_message"===o.type&&"owner"===o.sessionId){const e=s(a.chatActiveProjectId),t=s(o.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"===o.role){if(o.content===ca)return console.log("[crewswarm] Skipping SSE echo of locally-sent message"),void(ca=null);o.content!==la?(console.log("[crewswarm] Appending user bubble:",o.content.slice(0,50)),g("user",o.content),la=o.content):console.log("[crewswarm] Skipping duplicate user message")}else if("assistant"===o.role){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove());const e=String(o.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 ra=o.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"},a=t.firstElementChild;a&&a!==n&&(a.textContent=e.emoji+" "+e.name);const s=o.content??"";n._textNode?n._textNode.textContent=s:n.textContent=s,t.removeAttribute("id"),n.removeAttribute("id"),delete n.dataset.streamChunk,ra=o.content}else{t&&t.remove();const e=o.content===ra&&function(e,t){if(!e||null==t)return!1;const n=String(t).trim();if(!n)return!1;for(let a=e.children.length-1;a>=0;a--){const t=e.children[a];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,o.content);e?console.log("[crewswarm] Skipping duplicate assistant message"):(console.log("[crewswarm] Appending assistant bubble (final)"),g("assistant",o.content,o.fallbackModel,o.fallbackReason,o.model,o.engineUsed),ra=o.content)}}return void(l&&(l.scrollTop=l.scrollHeight))}if("pending_project"===o.type&&"owner"===o.sessionId&&o.pendingProject&&l)return ia(l,o.pendingProject),void(l.scrollTop=l.scrollHeight);if("agent_working"===o.type&&o.agent){const e=document.getElementById("coding-dot-"+o.agent);e&&(e.style.display="inline-flex")}if("agent_idle"===o.type&&o.agent){const e=document.getElementById("coding-dot-"+o.agent);e&&(e.style.display="none")}if("opencode_event"===o.type){const e=document.getElementById("ocFeed"),t=document.getElementById("ocFeedDot");if(!e)return;t&&(t.style.display="inline-block");const a=document.createElement("div");a.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(o.ts||Date.now()).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});let i="⚙️",r="";if("session_start"===o.kind){i="▶",a.style.borderLeft="3px solid var(--green-hi)";var n=o.dir||"";r="session started"+(n?" — "+n.split("/").pop():"")}else if("session_end"===o.kind)i="■",a.style.borderLeft="3px solid var(--text-3)",r="session ended",t&&(t.style.display="none");else if("file_edit"===o.kind)i="✏️",a.style.borderLeft="3px solid var(--amber)",r=(o.file||o.path||"")+(o.extra?' <span style="opacity:.5;">'+o.extra+"</span>":"");else if("error"===o.kind)i="✗",a.style.borderLeft="3px solid var(--red-hi)",a.style.color="var(--red-hi)",r=o.message||"error";else if("tool"===o.kind){const e={read_file:"var(--accent)",write_file:"var(--amber)",bash:"var(--purple)",list_directory:"var(--green)",grep:"var(--green)"}[o.tool]||"var(--text-2)";i="done"===o.phase?"✓":"→",a.style.borderLeft="3px solid "+e,a.style.color="done"===o.phase?"var(--text-2)":"var(--text-1)",r='<span style="color:'+e+';font-weight:600;">'+(o.tool||"")+"</span>"+(o.label?' <span style="opacity:.6;">'+o.label+"</span>":"")}for(a.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(a);e.children.length>80;)e.removeChild(e.firstChild);return void(e.scrollTop=e.scrollHeight)}if("agent_working"===o.type&&o.agent){const e="agent-spinner-"+(o.taskId||o.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>'+o.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"===o.type||o.from&&o.content){if(!o.from||!o.content)return;if(o._passthroughSummary)return;const e="agent-spinner-"+(o.taskId||o.from),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+o.from);return n&&n.remove(),g("🤖 "+o.from,o.content,!1,null,null,o.engineUsed),l&&(l.scrollTop=l.scrollHeight),void i(o.from+" finished a task")}if("task.timeout"===o.type&&o.agent){const e="agent-spinner-"+(o.taskId||o.agent),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+o.agent);n&&n.remove();const a="[crew-lead] Task to "+o.agent+" timed out (no reply in 90s). Consider @@SERVICE restart "+o.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>'+o.agent+'</strong> · no reply</div><div class="t">'+h(a)+"</div>",l.appendChild(e),l.scrollTop=l.scrollHeight}return void i("Task to "+o.agent+" timed out")}if("pipeline_progress"===o.type){let e;e=o.agents?"Wave "+(o.waveIndex+1)+"/"+o.totalWaves+" → "+o.agents.join(" + "):"Step "+(o.stepIndex+1)+"/"+o.total+" → "+o.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"===o.type){const e=document.createElement("div"),t=o.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 "+(o.waveIndex+1)+" quality gate: "+(o.issues||[]).join("; ")+t,void(l&&(l.appendChild(e),l.scrollTop=l.scrollHeight))}if("project_launched"===o.type&&o.project){const e=o.project.projectId||o.project.id;return void setTimeout(async()=>{await mn(),e&&En(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 "'+(o.project.name||e)+'" registered — selected in chat',t.appendChild(n),t.scrollTop=t.scrollHeight}},800)}if("pipeline_done"===o.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"===o.type&&o.approvalId)return void function(e,t,n){if(document.getElementById("cmd-approval-"+e))return;const a=document.createElement("div");a.id="cmd-approval-"+e,a.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 o=document.createElement("div");o.style.cssText="font-size:13px;font-weight:600;color:var(--text-1);",o.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),a.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),a.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),a.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),a.appendChild(o),a.appendChild(s),a.appendChild(r),a.appendChild(p),a.appendChild(g),document.body.appendChild(a)}(o.approvalId,o.agent,o.cmd);if("telemetry"===o.type&&o.payload){window._telemetryEvents=window._telemetryEvents||[],window._telemetryEvents.push(o.payload),window._telemetryEvents.length>100&&window._telemetryEvents.shift();const e=document.getElementById("toolMatrixView");e&&e.classList.contains("active")&&An(window._telemetryEvents)}}catch{}else console.warn("[crewswarm] SSE message with null/empty data")},ea.onopen=()=>{console.log("[crewswarm] SSE connection opened"),window._sseReconnectDelay=2e3},ea.onerror=e=>{console.error("[crewswarm] SSE error:",e),ea.close(),ea=null,window._sseReconnectTimer&&clearTimeout(window._sseReconnectTimer),window._sseReconnectTimer=setTimeout(()=>{window._sseReconnectTimer=null,window._sseReconnectDelay=Math.min(2*(window._sseReconnectDelay||2e3),3e4),ta()},window._sseReconnectDelay||2e3)}}const na=[{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 aa(){const e=document.getElementById("cmdAllowlistItems"),t=document.getElementById("cmdPresets");if(!e)return;const n=(await o("/api/cmd-allowlist").catch(()=>({list:[]}))).list||[];t&&(t.innerHTML="",na.forEach(function(e){const a=n.includes(e.pattern),o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 6px;border-radius:6px;transition:background 0.1s;",o.onmouseover=function(){o.style.background="var(--bg-hover)"},o.onmouseout=function(){o.style.background=""};const s=document.createElement("input");s.type="checkbox",s.checked=a,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)),aa()};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,o.appendChild(s),o.appendChild(r),o.appendChild(l),t.appendChild(o)}));const a=new Set(na.map(function(e){return e.pattern})),s=t?n.filter(function(e){return!a.has(e)}):n;if(e.innerHTML="",s.length)for(const o 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=o;const a=document.createElement("button");a.textContent="✕",a.style.cssText="border:none;background:transparent;color:var(--text-3);cursor:pointer;font-size:14px;padding:0 4px;",a.title="Remove",a.onclick=async function(){await fetch("/api/cmd-allowlist",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:o})}).catch(e=>i("Failed to delete pattern: "+e.message,!0)),aa()},t.appendChild(n),t.appendChild(a),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 oa(){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="",aa())}window._telemetryEvents=window._telemetryEvents||[];const sa=()=>jn(On);function ia(e,{draftId:t,name:n,outputDir:a,roadmapMd:o}){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;">'+a+'</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(o)+" tasks</span>";const p=document.createElement("textarea");p.value=o,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||a)+"</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 ra="",la="",ca=null;const{loadChatHistory:da,waitForChatHistoryIdle:pa,chatAtAtInput:ma,chatKeydown:ua,sendChat:ga,clearChatHistory:ha,stopAll:va,killAll:fa,killPassthrough:ya,refreshSessionIndicator:wa,clearPassthroughSession:ba,resetSendButton:xa,handleImageUpload:Ca,toggleVoiceRecording:ka}=w({postJSON:r,getJSON:o,appendChatBubble:g,showNotification:i,state:a,getChatSessionId:()=>"owner",getChatActiveProjectId:()=>a.chatActiveProjectId,getCrewLeadInfo:()=>window._crewLeadInfo,appendRoadmapCard:ia,getLastAppendedAssistantContent:()=>ra,setLastAppendedAssistantContent:e=>{ra=e},setLastAppendedUserContent:e=>{la=e},setLastSentContent:e=>{ca=e}});async function Ea(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 o("/api/files?dir="+encodeURIComponent(n));if(!e.files||!e.files.length)return void c(t,"No files found in "+n);const a={};e.files.forEach(e=>{const t=e.path.split(".").pop().toLowerCase()||"other";a[t]||(a[t]=[]),a[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)a[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+" — "+a[t].length+" file"+(a[t].length>1?"s":"")+"</div>",r+='<div style="display:grid;gap:6px;">',a[t].sort((e,t)=>t.mtime-e.mtime).forEach(e=>{const t=e.path.replace(n+"/",""),a=Ba(e.mtime),o=Sa(e.size);r+='<div class="file-row">',r+='<div class="file-info"><span class="file-name">'+t+'</span><span class="file-meta">'+o+" · "+a+"</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(a){l(t,"Error: "+a.message)}}async function Ia(e,t){const n=document.getElementById("file-preview-pane"),a=document.getElementById("file-preview-content"),s=document.getElementById("file-preview-name");if(n){s.textContent=e.split("/").pop(),a.textContent="Loading...",n.style.display="block",n.scrollIntoView({behavior:"smooth",block:"nearest"});try{const t=await o("/api/file-content?path="+encodeURIComponent(e));a.textContent=t.content||"(empty)"}catch(i){a.textContent="Error: "+i.message}}}function Ta(){const e=document.getElementById("file-preview-pane");e&&(e.style.display="none")}function Ba(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 a=Math.floor(n/60);return a<24?a+"h ago":Math.floor(a/24)+"d ago"}function Sa(e){return e<1024?e+"B":e<1048576?(e/1024).toFixed(1)+"KB":(e/1024/1024).toFixed(1)+"MB"}function ja(){Vn(),document.getElementById("settingsView").classList.add("active"),$n("navSettings"),a.activeTab="settings",s();const e=(location.hash||"").replace("#settings/",""),t={system:"engines",telegram:"comms",whatsapp:"comms"}[e]||e;Aa(["usage","engines","comms","security","webhooks"].includes(t)?t:"usage")}function Aa(e){var t;["usage","engines","comms","security","webhooks"].forEach(t=>{const n=document.getElementById("stab-panel-"+t),a=document.getElementById("stab-"+t);n&&a&&(n.style.display=t===e?"usage"===t?"grid":"block":"none",a.classList.toggle("active",t===e))}),"usage"===e&&(Sn(),Nn()),"engines"===e&&(St(),jt(),At(),Pt(),Lt(),Mt(),_t(),Nt(),Ot(),Rt(),Ft(),Ht(),Dt(),zt(),Gt()),"comms"===e&&an(),"security"===e&&(aa(),$t()),(null==(t=document.getElementById("settingsView"))?void 0:t.classList.contains("active"))&&history.replaceState(null,"","#settings/"+e)}function Pa(){Vn(),document.getElementById("enginesView").classList.add("active"),$n("navEngines"),Fe()}null==(e=document.getElementById("attachImageBtn"))||e.addEventListener("click",()=>{document.getElementById("imageUpload").click()}),null==(t=document.getElementById("imageUpload"))||t.addEventListener("change",Ca),null==(n=document.getElementById("recordVoiceBtn"))||n.addEventListener("click",ka),window.loadChatHistory=da,window.getChatSessionId=Zn,window.selectProjectTab=e=>{const t=e&&String(e).trim()&&"undefined"!==e?e:"general",n=a.chatActiveProjectId;console.log("🔵 [TAB CLICK] START",t,"- from:",n);const o=document.getElementById("chatProjectTabs");if(!o)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");Wn(t),Array.from(o.children).forEach(e=>{e.classList.remove("active")});const s=Array.from(o.children).find(e=>e.dataset.projectId===t);s&&s.classList.add("active"),a.chatActiveProjectId=t;try{localStorage.setItem("crewswarm_chat_active_project_id",t)}catch{}Qn(t),console.log("🔵 [TAB CLICK] Updated state:",{projectId:a.chatActiveProjectId,sessionId:"owner",url:window.location.hash}),console.log("🔵 [TAB CLICK] Calling loadChatHistory()..."),da().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"!==Kn().view)return;const e=await Jn(),t=e&&"undefined"!==e?e:"general";t!==(a.chatActiveProjectId&&"undefined"!==a.chatActiveProjectId?a.chatActiveProjectId:"general")&&window.selectProjectTab&&window.selectProjectTab(t)})().catch(()=>{})}),qt({showSettings:ja,showSettingsTab:Aa}),Vt({getModels:F,populateModelDropdown:le}),lt({hideAllViews:Vn,setNavActive:$n,loadAgents:F}),We(),b({hideAllViews:Vn,setNavActive:$n});const La=async()=>{Vn(),$n("navBenchmarks");const e=document.getElementById("benchmarksView");e&&e.classList.add("active");const{showBenchmarks:t}=await Dn();t({hideAllViews:Vn,setNavActive:$n})};function Ma(){Vn(),document.getElementById("memoryView").classList.add("active"),$n("navMemory"),A()}function _a(){Vn(),document.getElementById("cliProcessView").classList.add("active"),$n("navCLI"),window.initCLIProcess&&window.initCLIProcess()}function Na(){Vn(),document.getElementById("toolMatrixView").classList.add("active"),$n("navToolMatrix"),In()}async function Oa(){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 a=await fetch("/proxy-webhook/"+e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),o=await a.json();n.textContent=o.ok?"✅ Sent to RT bus":"❌ "+(o.error||"failed"),n.style.color=o.ok?"var(--green)":"var(--red)"}catch(a){n.textContent="❌ "+a.message,n.style.color="var(--red)"}}async function Ra(){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 Fa(){fn({hideAllViews:Vn,setNavActive:$n})}function Ha(){vn({hideAllViews:Vn,setNavActive:$n})}on({showChat:Yn,showBuild:Fa}),zn(),setInterval(zn,3e4),(async()=>{try{const e=(await o("/api/projects")).projects||[];a.projectsData={},e.forEach(e=>{a.projectsData[e.id]=e}),sn(e),s(),"#projects"===location.hash&&Ha()}catch{}})(),document.getElementById("refreshBtn").onclick=Gn,document.getElementById("runBuildBtn").onclick=rn,document.getElementById("continuousBuildBtn").onclick=ln,document.getElementById("stopBuildBtn").onclick=cn,document.getElementById("stopContinuousBtn").onclick=dn,document.getElementById("enhancePromptBtn").onclick=pn,Rn(),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(),a=document.getElementById("npFeaturesDoc").value.trim();if(e&&n)try{const o=await r("/api/projects",{name:e,description:t,outputDir:n,featuresDoc:a});i(`Project "${o.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="",mn()}catch(o){i("Failed: "+o.message,!0)}else i("Name and output directory required",!0)};const Da={chat:Yn,"swarm-chat":x,swarm:Ge,rt:ze,dlq:De,files:Xn,services:L,agents:R,models:Je,settings:ja,engines:Pa,skills:be,"run-skills":we,benchmarks:La,"tool-matrix":Na,build:Fa,messaging:Kt,projects:Ha,contacts:Le,memory:Ma,workflows:I,"cli-process":_a,prompts:de,testing:me};for(const[qa,Ka]of Object.entries(Da)){const e=Ka,t=function(...t){const n=location.hash||"";return"chat"===qa?n.startsWith("#chat")||history.replaceState(null,"","#chat"):history.replaceState(null,"","#"+qa),e(...t)};Da[qa]=t,window[e.name]=t}function za(e){const t=String(e||"chat").split("?")[0].split("/")[0];(Da[t]||Da.chat)()}(async()=>{if(await v())return;const{view:e,subtab:t}=Kn();"1"===new URLSearchParams(window.location.search).get("focus")?setTimeout(()=>{const e=document.getElementById("chatInput");e&&(za("chat"),e.focus())},500):(za(e||"chat"),"settings"===e&&t&&Aa(t))})(),window.addEventListener("hashchange",()=>{const{view:e,subtab:t}=Kn(),n=Va[e];n?(n(),"settings"===e&&t&&Aa(t)):Yn()}),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)),Gn(),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 a of n)for(const n of a.addedNodes)1===n.nodeType&&(n.matches&&n.matches('input[type="password"]')?e(n):t(n))}).observe(document.body,{childList:!0,subtree:!0})}();const Ga={showChat:Yn,showSwarm:Ge,showRT:ze,showBuild:Fa,showFiles:Xn,showDLQ:De,showProjects:Ha,showAgents:R,showModels:Je,showEngines:Pa,showSkills:be,showRunSkills:we,showBenchmarks:La,showToolMatrix:Na,showServices:L,showTesting:me,refreshTesting:()=>me(),runTests:e=>ye(e),stopTests:()=>fe(),loadRunDetail:e=>ve(e),runSingleFile:(e,t)=>he(e,t),toggleFailure:e=>ge(e),copyText:e=>ue(e),showSettings:ja,pickFolder:e=>qn(e),loadFiles:e=>Ea(),clearChatHistory:ha,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:ga,stopAll:va,killAll:fa,stopPassthrough:ya,clearPassthroughSession:ba,loadServices:M,saveRTToken:Tt,lockConfig:It,unlockConfig:Et,startCrew:H,toggleEmojiPicker:e=>ae(e),bulkSetRoute:(e,t)=>oe(e,t),loadSpending:_n,loadCrewCliStats:Mn,resetSpending:Ln,saveGlobalCaps:Pn,loadOcStats:sa,addAllowlistPattern:oa,sendTestWebhook:Oa,startTgBridge:tn,stopTgBridge:en,saveTgConfig:Zt,loadTelegramSessions:Xt,loadTgMessages:Yt,startWaBridge:Qt,stopWaBridge:Jt,saveWaConfig:Wt,loadWaMessages:Ut,saveOpencodeSettings:kt,saveOpencodeModel:Ct,saveGlobalFallback:xt,toggleBgConsciousness:bt,toggleCursorWaves:wt,toggleTmuxBridge:yt,toggleAutonomousMentions:ft,toggleClaudeCode:vt,toggleCodexExecutor:ht,toggleGeminiCliExecutor:gt,toggleCrewCliExecutor:ut,toggleOpencodeExecutor:mt,saveGlobalOcLoop:pt,saveGlobalOcLoopRounds:dt,savePassthroughNotify:ct,toggleAddSkill:Te,toggleImportSkill:Ie,importSkillFromUrl:Ee,showSkills:be,saveSkill:ke,cancelSkillForm:Ce,loadRunSkills:xe,loadBenchmarks:async()=>(await Dn()).loadBenchmarks(),loadBenchmarkLeaderboard:async()=>(await Dn()).loadBenchmarkLeaderboard(),loadBenchmarkTasks:async()=>(await Dn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Dn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Dn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Dn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadEngines:Fe,toggleImportEngine:Re,importEngineFromUrl:Oe,deleteEngine:e=>He(e),loadToolMatrix:In,loadBuildProjectPicker:un,scrollRTToBottom:()=>{const e=document.getElementById("rtView");e&&(e.scrollTop=e.scrollHeight)},toggleRTPause:Ve,clearRTMessages:$e,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:Ta,previewFile:(e,t)=>Ia(e),replayDLQ:e=>Ke(e),deleteDLQ:e=>qe(e),runSkillFromUI:e=>Se(e),editSkill:e=>je(e),deleteSkill:e=>Ae(e),restartAgentFromUI:e=>Tn(e),saveSearchTool:e=>et(e),testSearchTool:e=>Ye(e),saveBuiltinKey:e=>nt(e),testBuiltinProvider:e=>Ze(e),fetchBuiltinModels:(e,t)=>ot(e,t),saveOauthModel:e=>rt(e),testOauthProvider:e=>it(e),showOauthModels:e=>st(e),saveKey:e=>tt(e),testKey:e=>Xe(e),fetchModels:(e,t)=>at(e,t),toggleKeyVis:(e,t)=>Qe(e,t),toggleAgentBody:e=>D(e),deleteAgent:e=>te(e),saveAgentModel:e=>Q(e),saveAgentFallback:e=>Z(e),saveAgentVoice:e=>X(e),toggleEmojiPicker:e=>ae(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=a.projects)?void 0:t.find(t=>t.id===e);n&&n.running?Cn(e):kn(e)},"edit-roadmap":e=>{var t;const n=null==(t=a.projects)?void 0:t.find(t=>t.id===e);n&&xn(e,n.roadmapFile)},"retry-failed":e=>{var t;const n=null==(t=a.projects)?void 0:t.find(t=>t.id===e);n&&bn(n.roadmapFile)},"save-roadmap":e=>wn(e),"reset-failed":e=>yn(e),showSettingsTab:e=>Aa(e)};let $a=!1;document.addEventListener("touchstart",e=>{if(!(e.target instanceof Element))return;e.target.closest("[data-action]")&&($a=!0,setTimeout(()=>{$a=!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($a)return void e.preventDefault();e.stopPropagation();const n=t.dataset.action,a=Ga[n];if(!a)return void console.warn("[crewswarm] unknown data-action:",n);const o=t.dataset.arg??null,s=t.dataset.arg2??null,i="1"===t.dataset.self;null!==o&&null!==s?a(o,s):null!==o&&i?a(o,t):null!==o?a(o):i?a(t):a()}),document.addEventListener("change",e=>{const t=e.target.closest("[data-onchange]");if(!t)return;const n=Ga[t.dataset.onchange];if(!n)return;const a="this.value"===t.dataset.onchangeArg?t.value:null;null!==a?n(a):n()}),document.addEventListener("DOMContentLoaded",()=>{f("activeTasksPanel"),Me();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(Un()!==n)return void(window.location.hash=n);const a=Va[n];a&&a()})});const t=document.getElementById("chatInput");t&&!t.dataset.boundChatComposer&&(t.dataset.boundChatComposer="1",t.addEventListener("keydown",ua),t.addEventListener("input",ma));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(),ga()}));const a=document.getElementById("cmdAllowlistInput");a&&a.addEventListener("keydown",e=>{"Enter"===e.key&&oa()});const o=document.getElementById("waAllowedNumbers");o&&o.addEventListener("input",nn);const s=document.getElementById("skillSearch");s&&s.addEventListener("input",e=>Be(e.target.value));const i=document.getElementById("passthroughEngine");i&&i.addEventListener("change",()=>{wa(),function(){const e=document.getElementById("passthroughEngine"),t=document.getElementById("passthroughModel");if(!e||!t)return;const n=e.value,a={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||!a[n])return void(t.style.display="none");t.style.display="inline-block",t.innerHTML="";let o=null;for(const s of a[n])if(s.optgroup)o=document.createElement("optgroup"),o.label=s.optgroup,t.appendChild(o);else{const e=document.createElement("option");e.value=s.value,e.textContent=s.label,o?o.appendChild(e):t.appendChild(e)}}(),xa()});const r=document.getElementById("chatProjectSelect");r&&r.addEventListener("change",wa);const l=document.getElementById("passthroughModel");l&&l.addEventListener("change",()=>{xa()})},{once:!0});const Va={chat:Yn,"swarm-chat":x,swarm:Ge,rt:ze,build:Fa,files:Xn,dlq:De,projects:Ha,contacts:Le,agents:R,models:Je,engines:Pa,skills:be,"run-skills":we,waves:()=>{Vn(),document.getElementById("wavesView").style.display="block",$n("navWaves")},workflows:I,benchmarks:La,"tool-matrix":Na,memory:Ma,"cli-process":_a,services:L,prompts:de,testing:me,settings:ja};document.addEventListener("click",e=>{const t=e.target.closest("[data-view]");if(t){const e=t.dataset.view,n=Va[e];return void(n&&(Un()!==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}`,Aa(e)}const a=e.target.closest("[data-toggle-child]");if(a){const e=a.dataset.toggleChild,t=a.parentElement&&a.parentElement.querySelector(e);t&&(t.style.display="none"===t.style.display?"block":"none")}const o=e.target.closest("[data-toggle-sibling]");o&&o.nextElementSibling&&o.nextElementSibling.classList.toggle(o.dataset.toggleSibling)}),Object.assign(window,{addAllowlistPattern:oa,applyNewAgentToolPreset:ie,applyPromptPreset:se,bulkSetRoute:oe,cancelSkillForm:Ce,chatAtAtInput:ma,chatKeydown:ua,clearChatHistory:ha,filterSkills:Be,loadAllUsage:Nn,loadBenchmarkLeaderboard:async()=>(await Dn()).loadBenchmarkLeaderboard(),loadBenchmarks:async()=>(await Dn()).loadBenchmarks(),loadBenchmarkTasks:async()=>(await Dn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Dn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Dn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Dn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadBuildProjectPicker:un,loadFiles:Ea,loadCrewCliStats:Mn,loadOcStats:sa,loadRunSkills:xe,loadServices:M,loadSpending:_n,loadTelegramSessions:Xt,loadTgMessages:Yt,loadToolMatrix:In,loadWaMessages:Ut,onBuildProjectChange:hn,onChatProjectChange:gn,pickFolder:qn,renderWaContactRows:nn,resetSpending:Ln,approveSkill:async function(e){try{await fetch("/api/skills/approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Approved"),Ra()}catch(t){i("Failed: "+t.message,"error")}},loadPendingApprovals:Ra,rejectSkill:async function(e){try{await fetch("/api/skills/reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Rejected"),Ra()}catch(t){i("Failed: "+t.message,"error")}},saveGlobalCaps:Pn,saveGlobalFallback:xt,saveBgConsciousnessModel:Bt,saveOpencodeSettings:kt,saveRTToken:Tt,saveSkill:ke,saveTgConfig:Zt,saveWaConfig:Wt,sendChat:ga,sendTestWebhook:Oa,showAgents:R,showBenchmarks:La,showBuild:Fa,showChat:Yn,showContacts:Le,showDLQ:De,showFiles:Xn,showModels:Je,showProjects:Ha,showRT:ze,showRunSkills:we,showServices:L,showSettings:ja,showSettingsTab:Aa,showSkills:be,showSwarm:Ge,showToolMatrix:Na,showMemoryView:Ma,startCrew:H,startTgBridge:tn,startWaBridge:Qt,stopTgBridge:en,stopWaBridge:Jt,toggleAddSkill:Te,toggleBgConsciousness:bt,toggleCursorWaves:wt,toggleTmuxBridge:yt,toggleClaudeCode:vt,toggleEmojiPicker:ae,updateSkillAuthFields:Pe,navigateTo:za,renderStatusBadge:p,showLoading:d,showEmpty:c,showError:l,loadContacts:Ne,applyContactFilters:_e,applyToolPreset:ne,closePreviewPane:Ta,deleteAgent:te,deleteSkill:Ae,editSkill:je,fetchBuiltinModels:ot,fetchModels:at,previewFile:Ia,resetAgentSession:ee,restartAgentFromUI:Tn,restartService:N,runSkillFromUI:Se,saveAgentFallback:Z,saveAgentVoice:X,saveAgentIdentity:Y,saveAgentModel:Q,saveAgentPrompt:J,saveAgentTools:W,saveBuiltinKey:nt,saveCursorCliConfig:U,saveClaudeCodeConfig:K,saveGeminiCliConfig:q,saveKey:tt,saveOpenCodeConfig:V,saveOpenCodeFallback:$,saveSearchTool:et,saveCodexConfig:G,setRoute:z,stopService:_,testBuiltinProvider:Ze,testKey:Xe,testSearchTool:Ye,toggleAgentBody:D,toggleKeyVis:Qe});
@@ -0,0 +1 @@
1
+ import{s as t,g as e,d as o}from"./core-utils-CmOkXgzi.js";import{e as n,l as i}from"./tab-usage-tab-BIOOnB-Y.js";var l=null,a=null,s=null;function r(){var t=l,e=a,o=s,n=document.getElementById("gtAgentCost"),i=document.getElementById("gtOcCost"),r=document.getElementById("gtCrewCliCost"),d=document.getElementById("gtTotal");n&&(null!==t&&(n.textContent="$"+t.toFixed(4)),null!==e&&(i.textContent="$"+e.toFixed(4)),null!==o&&r&&(r.textContent="$"+o.toFixed(4)),null!==t&&null!==e&&null!==o&&(d.textContent="$"+(t+e+o).toFixed(4)))}function d(t){a=t,r()}function c(t){var e=document.getElementById("grandTotalDays"),o=document.getElementById("spendingDays"),n=document.getElementById("ocStatsDays"),i=document.getElementById("crewCliDays");e&&(e.value=String(t)),o&&(o.value=String(t)),n&&(n.value=String(t)),i&&(i.value=String(t))}async function p(){var t;c(parseInt((null==(t=document.getElementById("grandTotalDays"))?void 0:t.value)||"14")),l=null,a=null,s=null,document.getElementById("gtAgentCost").textContent="—",document.getElementById("gtOcCost").textContent="—";var e=document.getElementById("gtCrewCliCost");e&&(e.textContent="—"),document.getElementById("gtTotal").textContent="—",v(),i(d),y()}async function v(){var t;const i=document.getElementById("spendingWidget"),a=parseInt((null==(t=document.getElementById("spendingDays"))?void 0:t.value)||"1");c(a);try{{const t=(await e("/api/token-usage").catch(function(){return{}})).byDay||{},o=a<=1?(new Date).toISOString().slice(0,10):new Date(Date.now()-864e5*a).toISOString().slice(0,10),d=Object.keys(t).filter(function(t){return t>=o}).sort().reverse();if(!d.length)return i.innerHTML='<div style="color:var(--text-3);">No data for this period.</div>',l=0,void r();const c={};var s=0;d.forEach(function(e){const o=t[e].byModel||{};Object.entries(o).forEach(function(t){var e=t[0],o=t[1];c[e]||(c[e]={prompt:0,completion:0}),c[e].prompt+=o.prompt||0,c[e].completion+=o.completion||0,(o.prompt||0)+(o.completion||0)})}),s=n(c);let p='<div style="margin-bottom:10px;display:flex;justify-content:space-between;align-items:center;"><span style="font-size:12px;color:var(--text-3);">'+(a<=1?"Today":"Last "+a+" days &middot; "+d.length+" days of data")+'</span><span style="font-size:16px;font-weight:700;color:var(--yellow);">$'+s.toFixed(4)+"</span></div>";const v=Math.max(...d.map(function(e){return n(t[e].byModel||{})}),1e-4),y=(new Date).toISOString().slice(0,10);p+='<div style="display:flex;flex-direction:column;gap:3px;margin-bottom:12px;">',d.forEach(function(e){const o=n(t[e].byModel||{}),i=Math.max(o/v*100,o>0?2:0),l=e===y,a=((t[e].prompt||0)+(t[e].completion||0))/1e3;p+='<div style="display:flex;align-items:center;gap:8px;font-size:11px;"><span style="width:64px;color:var(--text-3);flex-shrink:0;">'+(l?"today":e.slice(5))+'</span><div style="flex:1;background:var(--bg-1);border-radius:3px;height:12px;overflow:hidden;"><div style="width:'+i.toFixed(1)+"%;height:100%;background:"+(l?"var(--accent)":"var(--green)")+';border-radius:3px;opacity:.8;"></div></div><span style="width:58px;text-align:right;color:var(--yellow);font-weight:600;">$'+o.toFixed(4)+'</span><span style="width:40px;text-align:right;color:var(--text-3);">'+a.toFixed(0)+"k</span></div>"}),p+="</div>";const x=Object.entries(c).sort(function(t,e){return n({b:e[1]})-n({a:t[1]})});x.length&&(p+='<div style="font-size:11px;color:var(--text-3);margin-bottom:4px;">By model</div>',x.slice(0,8).forEach(function(t){var e=t[0],o=t[1];const i=n({x:o}),l=((o.prompt||0)+(o.completion||0))/1e3;p+='<div style="display:flex;justify-content:space-between;font-size:11px;padding:2px 0;border-bottom:1px solid var(--border);"><code style="color:var(--accent);">'+e+'</code><span style="color:var(--text-2);">'+l.toFixed(1)+'k tok &middot; <span style="color:var(--yellow);">$'+i.toFixed(4)+"</span></span></div>"})),l=s,r(),i.innerHTML=p}}catch(d){o(i,"Error: "+d.message)}}async function y(){var t;const o=document.getElementById("crewCliStatsWidget");if(!o)return;const n=parseInt((null==(t=document.getElementById("crewCliDays"))?void 0:t.value)||"14");c(n),o.innerHTML='<div style="color:var(--text-3);font-size:12px;">Loading…</div>';try{const t=await e("/api/crew-cli-stats?days="+n);if(!t.ok||!Object.keys(t.byDay||{}).length)return o.innerHTML='<div style="color:var(--text-3);font-size:12px;">'+(t.error||"No crew-cli data found for this period.")+"</div>",s=0,void r();const i=t.byDay,l=Object.keys(i).sort().reverse(),a=t.totalCost||0,d=t.totalCalls||0,c=t.totalPromptTokens||0,p=t.totalCompletionTokens||0,v=Math.max(...l.map(function(t){return i[t].cost||0}),1e-4);let y='<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px;"><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--yellow);">$'+a.toFixed(4)+'</div><div style="font-size:11px;color:var(--text-3);">total cost</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--accent);">'+d.toLocaleString()+'</div><div style="font-size:11px;color:var(--text-3);">LLM calls</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--green);">'+(c/1e6).toFixed(2)+'M</div><div style="font-size:11px;color:var(--text-3);">input tokens</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--green);">'+(p/1e6).toFixed(2)+'M</div><div style="font-size:11px;color:var(--text-3);">output tokens</div></div></div>';const x=(new Date).toISOString().slice(0,10);y+='<div style="display:flex;flex-direction:column;gap:4px;margin-bottom:16px;">',l.forEach(function(t){const e=i[t],o=Math.max(e.cost/v*100,e.cost>0?2:0),n=t===x,l=((e.prompt_tokens||0)+(e.completion_tokens||0))/1e6;y+='<div style="display:flex;align-items:center;gap:8px;font-size:11px;"><span style="width:70px;color:var(--text-3);flex-shrink:0;">'+(n?"today":t.slice(5))+'</span><div style="flex:1;background:var(--bg-1);border-radius:3px;height:16px;overflow:hidden;"><div style="width:'+o.toFixed(1)+"%;height:100%;background:"+(n?"var(--accent)":"var(--purple, #a78bfa)")+';border-radius:3px;opacity:0.85;"></div></div><span style="width:60px;text-align:right;color:var(--yellow);font-weight:600;">$'+e.cost.toFixed(4)+'</span><span style="width:50px;text-align:right;color:var(--text-3);">'+l.toFixed(2)+'M</span><span style="width:36px;text-align:right;color:var(--text-3);">'+(e.calls||0)+"</span></div>"}),y+="</div>";const g={};l.forEach(function(t){Object.entries(i[t].byModel||{}).forEach(function(t){var e=t[0],o=t[1];g[e]||(g[e]={cost:0,calls:0}),g[e].cost+=o.cost||0,g[e].calls+=o.calls||0})});const u=Object.entries(g).sort(function(t,e){return e[1].cost-t[1].cost});u.length&&(y+='<div style="font-size:11px;color:var(--text-3);margin-bottom:4px;">By model</div>',u.slice(0,8).forEach(function(t){var e=t[0],o=t[1];y+='<div style="display:flex;justify-content:space-between;font-size:11px;padding:2px 0;border-bottom:1px solid var(--border);"><code style="color:var(--accent);">'+e+'</code><span style="color:var(--text-2);">'+o.calls+' calls &middot; <span style="color:var(--yellow);">$'+o.cost.toFixed(4)+"</span></span></div>"})),s=a,r(),o.innerHTML=y}catch(i){o.innerHTML='<div style="color:var(--text-3);font-size:12px;">Error: '+i.message+"</div>",s=0,r()}}async function x(){if(confirm("Reset today's spending counters?"))try{await fetch("/api/spending/reset",{method:"POST",headers:{"content-type":"application/json"},body:"{}"}),v(),t("Spending reset")}catch(e){t("Reset failed",!0)}}async function g(){const e=parseInt(document.getElementById("gcapTokens").value)||null,o=parseFloat(document.getElementById("gcapCost").value)||null;t('Add to ~/.crewswarm/crewswarm.json: "globalSpendingCaps": {"dailyTokenLimit":'+(e||"null")+',"dailyCostLimitUSD":'+(o||"null")+"}","warning")}export{v as a,p as b,d as c,y as l,x as r,g as s};