crewswarm 0.8.1-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +155 -0
- package/LICENSE +21 -0
- package/README.md +316 -0
- package/apps/dashboard/dist/assets/chat-core-BwSoInmZ.js +1 -0
- package/apps/dashboard/dist/assets/chat-core-BwSoInmZ.js.br +0 -0
- package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js +1 -0
- package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js.br +0 -0
- package/apps/dashboard/dist/assets/components-CSUb80ze.js +1 -0
- package/apps/dashboard/dist/assets/components-CSUb80ze.js.br +0 -0
- package/apps/dashboard/dist/assets/core-utils-CAVnDoe1.js +1 -0
- package/apps/dashboard/dist/assets/core-utils-CAVnDoe1.js.br +0 -0
- package/apps/dashboard/dist/assets/index-CF0aJRtC.css +1 -0
- package/apps/dashboard/dist/assets/index-CF0aJRtC.css.br +0 -0
- package/apps/dashboard/dist/assets/index-Px49zu76.js +2 -0
- package/apps/dashboard/dist/assets/index-Px49zu76.js.br +0 -0
- package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js +1 -0
- package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
- package/apps/dashboard/dist/assets/setup-wizard-i3eEixlo.js +1 -0
- package/apps/dashboard/dist/assets/setup-wizard-i3eEixlo.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-agents-tab-BThdsdJY.js +1 -0
- package/apps/dashboard/dist/assets/tab-agents-tab-BThdsdJY.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-benchmarks-tab-DfCuAClu.js +1 -0
- package/apps/dashboard/dist/assets/tab-comms-tab-eHpOSBhG.js +1 -0
- package/apps/dashboard/dist/assets/tab-comms-tab-eHpOSBhG.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-contacts-tab-yEegNyO4.js +1 -0
- package/apps/dashboard/dist/assets/tab-contacts-tab-yEegNyO4.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-engines-tab-C3DYxTwy.js +1 -0
- package/apps/dashboard/dist/assets/tab-engines-tab-C3DYxTwy.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-memory-tab-C59BYFQD.js +1 -0
- package/apps/dashboard/dist/assets/tab-memory-tab-C59BYFQD.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-models-tab-9Ur7pXWA.js +1 -0
- package/apps/dashboard/dist/assets/tab-models-tab-9Ur7pXWA.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-pm-loop-tab-D7mnDelU.js +1 -0
- package/apps/dashboard/dist/assets/tab-pm-loop-tab-D7mnDelU.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-projects-tab-C6h2Mv1K.js +1 -0
- package/apps/dashboard/dist/assets/tab-projects-tab-C6h2Mv1K.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-prompts-tab-C0wZvWK3.js +1 -0
- package/apps/dashboard/dist/assets/tab-prompts-tab-C0wZvWK3.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-services-tab-DBj_w3bc.js +1 -0
- package/apps/dashboard/dist/assets/tab-services-tab-DBj_w3bc.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-settings-tab-ezeqAjZk.js +1 -0
- package/apps/dashboard/dist/assets/tab-settings-tab-ezeqAjZk.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-skills-tab-BYdU2whk.js +1 -0
- package/apps/dashboard/dist/assets/tab-skills-tab-BYdU2whk.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-spending-tab-Bg6w9t_p.js +1 -0
- package/apps/dashboard/dist/assets/tab-spending-tab-Bg6w9t_p.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BBV9HB2X.js +1 -0
- package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BBV9HB2X.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-swarm-tab-ChqLlEVs.js +1 -0
- package/apps/dashboard/dist/assets/tab-swarm-tab-ChqLlEVs.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-usage-tab-B2UWXenJ.js +1 -0
- package/apps/dashboard/dist/assets/tab-usage-tab-B2UWXenJ.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js +1 -0
- package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-workflows-tab-6QSXLJ0i.js +1 -0
- package/apps/dashboard/dist/assets/tab-workflows-tab-6QSXLJ0i.js.br +0 -0
- package/apps/dashboard/dist/favicon.png +0 -0
- package/apps/dashboard/dist/index.html +6466 -0
- package/apps/dashboard/dist/index.html.br +0 -0
- package/apps/dashboard/dist/index.html.gz +0 -0
- package/apps/dashboard/dist/signup.html +446 -0
- package/apps/dashboard/index.html +6442 -0
- package/apps/dashboard/package.json +15 -0
- package/apps/dashboard/src/app.js +2823 -0
- package/apps/dashboard/src/app.js.br +0 -0
- package/apps/dashboard/src/app.js.gz +0 -0
- package/apps/dashboard/src/chat/chat-actions.js +1847 -0
- package/apps/dashboard/src/chat/chat-actions.js.br +0 -0
- package/apps/dashboard/src/chat/unified-messages.js +327 -0
- package/apps/dashboard/src/chat/unified-messages.js.br +0 -0
- package/apps/dashboard/src/cli-process.js +208 -0
- package/apps/dashboard/src/cli-process.js.br +0 -0
- package/apps/dashboard/src/cli-process.js.gz +0 -0
- package/apps/dashboard/src/components/active-tasks-panel.js +175 -0
- package/apps/dashboard/src/components/active-tasks-panel.js.br +0 -0
- package/apps/dashboard/src/core/api.js +18 -0
- package/apps/dashboard/src/core/api.js.br +0 -0
- package/apps/dashboard/src/core/dom.js +220 -0
- package/apps/dashboard/src/core/dom.js.br +0 -0
- package/apps/dashboard/src/core/state.js +91 -0
- package/apps/dashboard/src/core/state.js.br +0 -0
- package/apps/dashboard/src/core/task-manager.js +134 -0
- package/apps/dashboard/src/core/task-manager.js.br +0 -0
- package/apps/dashboard/src/orchestration-status.js +127 -0
- package/apps/dashboard/src/orchestration-status.js.br +0 -0
- package/apps/dashboard/src/setup-wizard.js +555 -0
- package/apps/dashboard/src/setup-wizard.js.br +0 -0
- package/apps/dashboard/src/styles.css +2085 -0
- package/apps/dashboard/src/styles.css.br +0 -0
- package/apps/dashboard/src/styles.css.gz +0 -0
- package/apps/dashboard/src/tabs/agents-tab.js +2237 -0
- package/apps/dashboard/src/tabs/agents-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/benchmarks-tab.js +229 -0
- package/apps/dashboard/src/tabs/benchmarks-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/comms-tab.js +955 -0
- package/apps/dashboard/src/tabs/comms-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/contacts-tab.js +654 -0
- package/apps/dashboard/src/tabs/contacts-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/engines-tab.js +175 -0
- package/apps/dashboard/src/tabs/engines-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/memory-tab.js +182 -0
- package/apps/dashboard/src/tabs/memory-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/models-tab.js +441 -0
- package/apps/dashboard/src/tabs/models-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/pm-loop-tab.js +185 -0
- package/apps/dashboard/src/tabs/pm-loop-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/projects-tab.js +663 -0
- package/apps/dashboard/src/tabs/projects-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/projects-tab.js.gz +0 -0
- package/apps/dashboard/src/tabs/prompts-tab.js +160 -0
- package/apps/dashboard/src/tabs/prompts-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/services-tab.js +202 -0
- package/apps/dashboard/src/tabs/services-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/settings-tab.js +803 -0
- package/apps/dashboard/src/tabs/settings-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/skills-tab.js +284 -0
- package/apps/dashboard/src/tabs/skills-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/spending-tab.js +173 -0
- package/apps/dashboard/src/tabs/spending-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/swarm-chat-tab.js +660 -0
- package/apps/dashboard/src/tabs/swarm-chat-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/swarm-tab.js +538 -0
- package/apps/dashboard/src/tabs/swarm-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/usage-tab.js +390 -0
- package/apps/dashboard/src/tabs/usage-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/waves-tab.js +238 -0
- package/apps/dashboard/src/tabs/waves-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/workflows-tab.js +747 -0
- package/apps/dashboard/src/tabs/workflows-tab.js.br +0 -0
- package/apps/vibe/.crew/agent-memory/pipeline.json +249 -0
- package/apps/vibe/.crew/cost.json +17 -0
- package/apps/vibe/.crew/json-parse-metrics.jsonl +22 -0
- package/apps/vibe/.crew/pipeline-metrics.jsonl +22 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-0f90c392-2425-4ae5-850c-bd9d17b1d690.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-1c269dd9-a63f-4fba-af81-5cf08048ef06.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-288a7765-da24-4a22-89bc-1f3cc9b0562c.jsonl +1 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-2c78fd22-a657-4bd1-bc49-0679fb384409.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-3e6fe08d-3264-404a-8df3-aab7efef10e7.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-42eec610-57fe-4e09-9e7e-b315038495c2.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-4438eb4c-ae13-42b1-90e2-b043d8983be8.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-4740a9f5-86e7-44b6-a394-de433e291727.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-49e1da6a-957e-48fd-9220-415019e4f8e2.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-4c9251db-be68-427b-a3fc-a264f2b5778d.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-65e29a57-664d-4196-8109-017e364f182e.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-6aa04bc5-9593-4b1f-b58d-3bf2978cb602.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-6e1cba53-9b70-457e-99e0-59199149dd21.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-749f41cc-4dac-4204-be64-873a6080a0d2.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-74d68121-e181-4864-bd9a-c3211341dfaf.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-8509bc24-142d-4e07-b44a-a50bf99d1103.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-960339c6-07ca-43ce-9900-f6e1702b39b9.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-9c6480a9-7031-4146-b241-825b9a2d1de1.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-9fd42426-8492-4157-9d5f-e1537c060489.jsonl +2 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-ad6d40a3-2f5e-46a9-a345-47caaccc51aa.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-bc606133-8d5b-4535-8d85-f1a29cdaa981.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-c1a13ccd-634a-4d01-a4a7-1177b8a752ff.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-c7d27b42-249e-4bd4-8f26-6aa998110b8a.jsonl +5 -0
- package/apps/vibe/.crew/pipeline-runs/pipeline-cca2e9b9-4a34-4d25-a311-5c793fa7e91e.jsonl +5 -0
- package/apps/vibe/.crew/sandbox.json +7 -0
- package/apps/vibe/.crew/session.json +285 -0
- package/apps/vibe/.crew/training-data.jsonl +0 -0
- package/apps/vibe/.github/workflows/studio-quality.yml +37 -0
- package/apps/vibe/.studio-data/project-messages/chuck-norris.jsonl +12 -0
- package/apps/vibe/.studio-data/project-messages/general.jsonl +54 -0
- package/apps/vibe/.studio-data/project-messages/studio-local.jsonl +10 -0
- package/apps/vibe/ARCHITECTURE.md +3393 -0
- package/apps/vibe/QUICK-REFERENCE.md +211 -0
- package/apps/vibe/README.md +76 -0
- package/apps/vibe/ROADMAP.md +41 -0
- package/apps/vibe/STUDIO-SETUP-COMPLETE.md +35 -0
- package/apps/vibe/VISUAL-GUIDE.md +378 -0
- package/apps/vibe/capture-demo.mjs +160 -0
- package/apps/vibe/capture-vibe-assets.mjs +71 -0
- package/apps/vibe/capture-vibe-video.mjs +260 -0
- package/apps/vibe/check-buttons.js +41 -0
- package/apps/vibe/diagnose.html +106 -0
- package/apps/vibe/fix-buttons.js +103 -0
- package/apps/vibe/index.html +3401 -0
- package/apps/vibe/package-lock.json +920 -0
- package/apps/vibe/package.json +31 -0
- package/apps/vibe/public/favicon.png +0 -0
- package/apps/vibe/scripts/studio-pty-host.py +117 -0
- package/apps/vibe/server.mjs +1835 -0
- package/apps/vibe/src/main.js +2846 -0
- package/apps/vibe/src/register-all-languages.js +98 -0
- package/apps/vibe/start-studio.sh +11 -0
- package/apps/vibe/test/accessibility-tests.js +77 -0
- package/apps/vibe/test/browser-performance-audit.mjs +205 -0
- package/apps/vibe/test/performance-tests.js +120 -0
- package/apps/vibe/test/security-tests.js +213 -0
- package/apps/vibe/tests/e2e.local.mjs +54 -0
- package/apps/vibe/tests/server.smoke.mjs +106 -0
- package/apps/vibe/update_website.mjs +74 -0
- package/apps/vibe/vite.config.js +19 -0
- package/apps/vibe/watch-server.mjs +108 -0
- package/contrib/openclaw-plugin/README.md +199 -0
- package/contrib/openclaw-plugin/index.ts +306 -0
- package/contrib/openclaw-plugin/openclaw.plugin.json +41 -0
- package/contrib/openclaw-plugin/package.json +27 -0
- package/contrib/openclaw-plugin/skills/crewswarm/SKILL.md +88 -0
- package/crew-lead.mjs +649 -0
- package/engines/claude-code.json +36 -0
- package/engines/codex.json +37 -0
- package/engines/crew-cli.json +42 -0
- package/engines/cursor.json +40 -0
- package/engines/docker-sandbox.json +38 -0
- package/engines/gemini-cli.json +75 -0
- package/engines/opencode.json +31 -0
- package/gateway-bridge.mjs +1575 -0
- package/install.sh +738 -0
- package/lib/agent-registry.mjs +232 -0
- package/lib/agents/daemon.mjs +121 -0
- package/lib/agents/dispatch.mjs +225 -0
- package/lib/agents/permissions.mjs +90 -0
- package/lib/agents/platform-formatting.mjs +102 -0
- package/lib/agents/registry.mjs +81 -0
- package/lib/agents/tool-instructions.mjs +257 -0
- package/lib/agents/validation.mjs +75 -0
- package/lib/approval/policy-manager.mjs +221 -0
- package/lib/autoharness/index.mjs +391 -0
- package/lib/bridges/cli-executor.mjs +332 -0
- package/lib/bridges/gateway-ws.mjs +345 -0
- package/lib/bridges/integration.mjs +229 -0
- package/lib/bridges/rag-helper.mjs +90 -0
- package/lib/browser/opencode-passthrough-filter.js +44 -0
- package/lib/browser/passthrough-stderr.js +109 -0
- package/lib/chat/autonomous-mentions.mjs +373 -0
- package/lib/chat/history.mjs +82 -0
- package/lib/chat/mention-routing-intent.mjs +136 -0
- package/lib/chat/participants.mjs +95 -0
- package/lib/chat/project-messages-rag.mjs +265 -0
- package/lib/chat/project-messages.mjs +479 -0
- package/lib/chat/shared-chat-prompt-overlay.mjs +52 -0
- package/lib/chat/thread-binding.mjs +34 -0
- package/lib/chat/unified-history.mjs +223 -0
- package/lib/chat/unified-wrapper.mjs +41 -0
- package/lib/cli-process-tracker.mjs +228 -0
- package/lib/collections/index.mjs +433 -0
- package/lib/contacts/identity-linker.mjs +248 -0
- package/lib/contacts/index.mjs +341 -0
- package/lib/crew-judge/PROMPT.md +93 -0
- package/lib/crew-judge/judge.mjs +260 -0
- package/lib/crew-lead/agent-manager.mjs +125 -0
- package/lib/crew-lead/background.mjs +270 -0
- package/lib/crew-lead/brain.mjs +110 -0
- package/lib/crew-lead/chat-handler.mjs +2603 -0
- package/lib/crew-lead/chat-handler.mjs.bak +1274 -0
- package/lib/crew-lead/classifier.mjs +83 -0
- package/lib/crew-lead/http-server.mjs +4824 -0
- package/lib/crew-lead/intent.mjs +102 -0
- package/lib/crew-lead/interval-manager.mjs +41 -0
- package/lib/crew-lead/llm-caller.mjs +544 -0
- package/lib/crew-lead/prompts.mjs +392 -0
- package/lib/crew-lead/retry-manager.mjs +118 -0
- package/lib/crew-lead/tools.mjs +318 -0
- package/lib/crew-lead/wave-dispatcher.mjs +798 -0
- package/lib/crew-lead/waves-config.json +73 -0
- package/lib/crew-lead/waves-loader.mjs +110 -0
- package/lib/crew-lead/ws-router.mjs +428 -0
- package/lib/dispatch/parsers.mjs +299 -0
- package/lib/domain-planning/detector.mjs +196 -0
- package/lib/domain-planning/prompts/crew-pm-cli.md +96 -0
- package/lib/domain-planning/prompts/crew-pm-core.md +122 -0
- package/lib/domain-planning/prompts/crew-pm-frontend.md +111 -0
- package/lib/engines/crew-cli-sandbox.mjs +422 -0
- package/lib/engines/crew-cli.mjs +155 -0
- package/lib/engines/cursor-launcher.mjs +110 -0
- package/lib/engines/engine-registry.mjs +253 -0
- package/lib/engines/llm-direct.mjs +184 -0
- package/lib/engines/opencode.mjs +256 -0
- package/lib/engines/ouroboros.mjs +114 -0
- package/lib/engines/rt-envelope.mjs +1643 -0
- package/lib/engines/rt-envelope.mjs.backup-current +870 -0
- package/lib/engines/runners.mjs +1367 -0
- package/lib/gemini-cli-passthrough-noise.mjs +37 -0
- package/lib/integrations/code-search.mjs +259 -0
- package/lib/integrations/greptile.mjs +148 -0
- package/lib/integrations/multimodal.mjs +313 -0
- package/lib/integrations/telegram-streaming.mjs +153 -0
- package/lib/integrations/tts.mjs +312 -0
- package/lib/integrations/twitter-links.mjs +294 -0
- package/lib/memory/shared-adapter.mjs +296 -0
- package/lib/pipeline/manager.mjs +539 -0
- package/lib/preferences/extractor.mjs +347 -0
- package/lib/project-dir.mjs +20 -0
- package/lib/runtime/config.mjs +388 -0
- package/lib/runtime/dlq.mjs +170 -0
- package/lib/runtime/log-rotation.mjs +82 -0
- package/lib/runtime/logger.mjs +58 -0
- package/lib/runtime/memory.mjs +421 -0
- package/lib/runtime/paths.mjs +76 -0
- package/lib/runtime/project-dir.mjs +127 -0
- package/lib/runtime/spending.mjs +204 -0
- package/lib/runtime/startup-guard.mjs +291 -0
- package/lib/runtime/task-lease.mjs +234 -0
- package/lib/runtime/telemetry-schema.mjs +208 -0
- package/lib/runtime/telemetry.mjs +101 -0
- package/lib/runtime/utils.mjs +64 -0
- package/lib/skills/index.mjs +265 -0
- package/lib/tools/browser.mjs +135 -0
- package/lib/tools/executor.mjs +913 -0
- package/lib/types.d.ts +57 -0
- package/package.json +106 -0
- package/pm-loop.mjs +1626 -0
- package/prompts/coder-back.md +27 -0
- package/prompts/coder-front.md +27 -0
- package/prompts/coder.md +28 -0
- package/prompts/copywriter.md +17 -0
- package/prompts/fixer.md +39 -0
- package/prompts/frontend.md +23 -0
- package/prompts/github.md +24 -0
- package/prompts/main.md +39 -0
- package/prompts/pm-cli.md +95 -0
- package/prompts/pm-core.md +121 -0
- package/prompts/pm-frontend.md +110 -0
- package/prompts/pm.md +234 -0
- package/prompts/qa.md +44 -0
- package/prompts/security.md +19 -0
- package/scripts/build-crew-chat.sh +28 -0
- package/scripts/build-llms-full.mjs +52 -0
- package/scripts/chatmock-login.sh +16 -0
- package/scripts/chatmock-serve.sh +16 -0
- package/scripts/check-dashboard.mjs +88 -0
- package/scripts/crew-scribe.mjs +326 -0
- package/scripts/dashboard-helpers.mjs +391 -0
- package/scripts/dashboard-validation.mjs +198 -0
- package/scripts/dashboard.mjs +9717 -0
- package/scripts/dlq-replay.mjs +61 -0
- package/scripts/doctor.mjs +196 -0
- package/scripts/file-lock.mjs +186 -0
- package/scripts/fresh-machine-smoke.sh +323 -0
- package/scripts/generate-changelog.mjs +227 -0
- package/scripts/generate-openapi.mjs +334 -0
- package/scripts/health-check.mjs +229 -0
- package/scripts/install-docker.sh +213 -0
- package/scripts/mcp-server.mjs +1625 -0
- package/scripts/opencrew-rt-daemon.mjs +568 -0
- package/scripts/openswitchctl +646 -0
- package/scripts/refactor-configs.mjs +39 -0
- package/scripts/release-check.sh +46 -0
- package/scripts/resolve-node-bin.sh +25 -0
- package/scripts/restart-all-from-repo.sh +329 -0
- package/scripts/restart-crew-lead.sh +98 -0
- package/scripts/restart-dashboard.sh +104 -0
- package/scripts/restart-service.sh +274 -0
- package/scripts/run-accessibility-audit.mjs +356 -0
- package/scripts/run-integration-bounded.mjs +188 -0
- package/scripts/run-scheduled-pipeline.mjs +230 -0
- package/scripts/run.mjs +41 -0
- package/scripts/scan-skills.mjs +79 -0
- package/scripts/setup-firewall.sh +128 -0
- package/scripts/smoke-dispatch.mjs +149 -0
- package/scripts/smoke.sh +163 -0
- package/scripts/start-crew.mjs +328 -0
- package/scripts/start.mjs +146 -0
- package/scripts/swiftbar-restart-service.sh +19 -0
- package/scripts/sync-agents.mjs +152 -0
- package/scripts/sync-prompts.mjs +79 -0
- package/scripts/validate-config.mjs +337 -0
- package/scripts/wow.mjs +89 -0
- package/telegram-bridge.mjs +2421 -0
- package/unified-orchestrator.mjs +519 -0
- package/whatsapp-bridge.mjs +1481 -0
package/.env.example
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# crewswarm API Keys & Configuration
|
|
2
|
+
#
|
|
3
|
+
# Quick start:
|
|
4
|
+
# 1. Copy this file: cp .env.example .env
|
|
5
|
+
# 2. Add at least one API key below (Groq is free: https://console.groq.com/keys)
|
|
6
|
+
# 3. Run: bash install.sh
|
|
7
|
+
#
|
|
8
|
+
# Note: API keys can also be set via dashboard (Settings β Providers)
|
|
9
|
+
# or in ~/.crewswarm/crewswarm.json
|
|
10
|
+
|
|
11
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
12
|
+
# LLM Providers (Add at least one)
|
|
13
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
14
|
+
|
|
15
|
+
# ββ Groq (Recommended β free tier, fast inference) βββββββββββββββββββββββββββ
|
|
16
|
+
# Get key: https://console.groq.com/keys
|
|
17
|
+
# Models: llama-3.3-70b-versatile, mixtral-8x7b, gemma-2-9b
|
|
18
|
+
# GROQ_API_KEY=
|
|
19
|
+
|
|
20
|
+
# ββ Anthropic (Claude models β best reasoning) βββββββββββββββββββββββββββββββ
|
|
21
|
+
# Get key: https://console.anthropic.com/
|
|
22
|
+
# Models: claude-sonnet-4-5, claude-sonnet-3-5, claude-opus-3-5
|
|
23
|
+
# ANTHROPIC_API_KEY=
|
|
24
|
+
|
|
25
|
+
# ββ OpenAI (GPT models) βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
26
|
+
# Get key: https://platform.openai.com/api-keys
|
|
27
|
+
# Models: gpt-4o, o1, o3-mini
|
|
28
|
+
# OPENAI_API_KEY=
|
|
29
|
+
|
|
30
|
+
# ββ xAI / Grok (Reasoning, coding, vision) ββββββββββββββββββββββββββββββββββββ
|
|
31
|
+
# Get key: https://console.x.ai/
|
|
32
|
+
# Models: grok-3, grok-3-mini, grok-3-mini-fast
|
|
33
|
+
# XAI_API_KEY=
|
|
34
|
+
|
|
35
|
+
# ββ Google Gemini (Free tier available) ββββββββββββββββββββββββββββββββββββββ
|
|
36
|
+
# Get key: https://aistudio.google.com/apikey
|
|
37
|
+
# Models: gemini-2.0-flash-exp, gemini-2.5-pro
|
|
38
|
+
# GEMINI_API_KEY=
|
|
39
|
+
|
|
40
|
+
# ββ DeepSeek (Low cost, strong coding) βββββββββββββββββββββββββββββββββββββββ
|
|
41
|
+
# Get key: https://platform.deepseek.com/
|
|
42
|
+
# Models: deepseek-chat, deepseek-coder
|
|
43
|
+
# DEEPSEEK_API_KEY=
|
|
44
|
+
|
|
45
|
+
# ββ Cerebras (Ultra-fast β llama-3.3-70b at 2000 tok/s) ββββββββββββββββββββββ
|
|
46
|
+
# Get key: https://cloud.cerebras.ai/
|
|
47
|
+
# Models: llama-3.3-70b, llama-3.1-8b
|
|
48
|
+
# CEREBRAS_API_KEY=
|
|
49
|
+
|
|
50
|
+
# ββ Mistral (Open-weight models) ββββββββββββββββββββββββββββββββββββββββββββββ
|
|
51
|
+
# Get key: https://console.mistral.ai/
|
|
52
|
+
# Models: mistral-large-latest, mixtral-8x22b
|
|
53
|
+
# MISTRAL_API_KEY=
|
|
54
|
+
|
|
55
|
+
# ββ Perplexity (Research-optimized, web search) βββββββββββββββββββββββββββββββ
|
|
56
|
+
# Get key: https://www.perplexity.ai/settings/api
|
|
57
|
+
# Models: sonar-pro, sonar-reasoning
|
|
58
|
+
# PERPLEXITY_API_KEY=
|
|
59
|
+
|
|
60
|
+
# ββ OpenRouter (One key for 400+ models β Claude, GPT-4, Gemini, Hunter Alpha, Llama) β
|
|
61
|
+
# Get key: https://openrouter.ai/keys
|
|
62
|
+
# Models: anthropic/claude-sonnet-4, openai/gpt-4o, google/gemini-2.0-flash, hunter-alpha
|
|
63
|
+
# OPENROUTER_API_KEY=
|
|
64
|
+
|
|
65
|
+
# ββ NVIDIA NIM (Llama, Mistral, Phi on NVIDIA hardware) βββββββββββββββββββββββ
|
|
66
|
+
# Get key: https://build.nvidia.com/explore/discover
|
|
67
|
+
# Models: meta/llama-3.1-405b-instruct, mistralai/mixtral-8x22b-instruct-v0.1
|
|
68
|
+
# NVIDIA_API_KEY=
|
|
69
|
+
|
|
70
|
+
# ββ OpenCode (Multi-model router with free tier) βββββββββββββββββββββββββββββ
|
|
71
|
+
# Get key: https://opencode.com/signup
|
|
72
|
+
# Access GPT-5.1 Codex, Claude, and 50+ other models via one API
|
|
73
|
+
# Free tier: kimi-k2, qwen3, llama-3.3-70b (via Groq passthrough)
|
|
74
|
+
# OPENCODE_API_KEY=
|
|
75
|
+
|
|
76
|
+
# ββ Ollama (Local models β no API key needed) βββββββββββββββββββββββββββββββββ
|
|
77
|
+
# Download: https://ollama.com/download
|
|
78
|
+
# Run: ollama serve (default http://127.0.0.1:11434)
|
|
79
|
+
# Models: llama3.1, qwen2.5-coder, deepseek-r1
|
|
80
|
+
# OLLAMA_BASE_URL=http://127.0.0.1:11434
|
|
81
|
+
|
|
82
|
+
# ββ OpenAI (Local ChatGPT Plus/Pro via ChatMock) ββββββββββββββββββββββββββββββ
|
|
83
|
+
# Setup: https://github.com/RayBytes/ChatMock (port 8000)
|
|
84
|
+
# Use your ChatGPT Plus/Pro subscription instead of API credits
|
|
85
|
+
# OPENAI_LOCAL_BASE_URL=http://127.0.0.1:8000
|
|
86
|
+
|
|
87
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
88
|
+
# Optional: Web Search & Code Indexing
|
|
89
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
90
|
+
|
|
91
|
+
# ββ Greptile (Code search & repo indexing) ββββββββββββββββββββββββββββββββββββ
|
|
92
|
+
# Get key: https://app.greptile.com/api
|
|
93
|
+
# Status: β
Working β Can index GitHub repos, check status
|
|
94
|
+
# Note: Query endpoint not available via REST API (use MCP or web UI)
|
|
95
|
+
# GREPTILE_API_KEY=
|
|
96
|
+
|
|
97
|
+
# ββ Parallel (Deep research & web synthesis) ββββββββββββββββββββββββββββββββββ
|
|
98
|
+
# Get key: https://platform.parallel.ai/signup
|
|
99
|
+
# PARALLEL_API_KEY=
|
|
100
|
+
|
|
101
|
+
# ββ Brave Search (Fast web search ~700ms) βββββββββββββββββββββββββββββββββββββ
|
|
102
|
+
# Get key: https://api.search.brave.com/
|
|
103
|
+
# BRAVE_API_KEY=
|
|
104
|
+
|
|
105
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
106
|
+
# Configuration (Optional β sane defaults provided)
|
|
107
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
108
|
+
|
|
109
|
+
# ββ Ports βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
110
|
+
# CREW_LEAD_PORT=5010 # crew-lead HTTP API
|
|
111
|
+
# SWARM_DASH_PORT=4319 # Dashboard web UI
|
|
112
|
+
# WA_HTTP_PORT=3000 # WhatsApp bridge HTTP
|
|
113
|
+
|
|
114
|
+
# ββ Execution Engines βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
115
|
+
# CREWSWARM_OPENCODE_ENABLED=off # Route coding agents through OpenCode
|
|
116
|
+
# CREWSWARM_OPENCODE_MODEL= # Override per-agent model for OpenCode
|
|
117
|
+
# CREWSWARM_OPENCODE_TIMEOUT_MS=300000 # 5 minutes
|
|
118
|
+
|
|
119
|
+
# CREWSWARM_GEMINI_CLI_ENABLED=off # Route agents through Gemini CLI
|
|
120
|
+
# CREWSWARM_GEMINI_CLI_MODEL=gemini-2.0-flash # Which Gemini model
|
|
121
|
+
|
|
122
|
+
# CREWSWARM_ENGINE_LOOP=off # Ouroboros LLM β Engine loop
|
|
123
|
+
# CREWSWARM_ENGINE_LOOP_MAX_ROUNDS=10 # Max STEP iterations per loop
|
|
124
|
+
|
|
125
|
+
# ββ Timeouts ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
126
|
+
# CREWSWARM_ENGINE_IDLE_TIMEOUT_MS=300000 # Kill engine after 5min silence
|
|
127
|
+
# CREWSWARM_ENGINE_MAX_TOTAL_MS=1800000 # Absolute 30min ceiling
|
|
128
|
+
# CREWSWARM_DISPATCH_TIMEOUT_MS=120000 # Task dispatch timeout (2min)
|
|
129
|
+
# PM_AGENT_IDLE_TIMEOUT_MS=300000 # PM loop subprocess timeout
|
|
130
|
+
|
|
131
|
+
# ββ PM Loop Behavior ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
132
|
+
# PM_MAX_ITEMS=10 # Max roadmap items per run
|
|
133
|
+
# PM_MAX_CONCURRENT=1 # Parallel tasks (1=sequential)
|
|
134
|
+
# PM_CODER_AGENT=crew-coder # Override default coder
|
|
135
|
+
# PM_USE_QA=off # Include crew-qa quality gate
|
|
136
|
+
# PM_USE_SECURITY=off # Include crew-security audit
|
|
137
|
+
# PM_USE_SPECIALISTS=off # Route by keyword (frontendβcrew-coder-front)
|
|
138
|
+
# PM_SELF_EXTEND=off # Auto-generate roadmap items when empty
|
|
139
|
+
# PM_EXTEND_EVERY=5 # Self-extend every N items
|
|
140
|
+
# PM_USE_JUDGE=on # Call crew-judge after cycles
|
|
141
|
+
# PM_JUDGE_EVERY=5 # Judge decision every N items
|
|
142
|
+
# CREW_JUDGE_MODEL=groq/llama-3.3-70b-versatile # Model for judge (fast+cheap)
|
|
143
|
+
|
|
144
|
+
# ββ Background Consciousness (crew-main idle reflection) ββββββββββββββββββββββ
|
|
145
|
+
# CREWSWARM_BG_CONSCIOUSNESS=off
|
|
146
|
+
# CREWSWARM_BG_CONSCIOUSNESS_INTERVAL_MS=900000 # 15min idle interval
|
|
147
|
+
# CREWSWARM_BG_CONSCIOUSNESS_MODEL=groq/llama-3.1-8b-instant
|
|
148
|
+
|
|
149
|
+
# ββ Messaging Bridges (Telegram / WhatsApp) ββββββββββββββββββββββββββββββββββ
|
|
150
|
+
# TELEGRAM_ALLOWED_USERNAMES=yourusername # Comma-separated list
|
|
151
|
+
# WA_ALLOWED_NUMBERS=+15551234567 # International format
|
|
152
|
+
|
|
153
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
154
|
+
# For full reference: https://github.com/crewswarm/crewswarm/blob/main/AGENTS.md
|
|
155
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 crewswarm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# crewswarm
|
|
2
|
+
|
|
3
|
+
**Local-first AI orchestration for people who want real files, real tools, and real control.**
|
|
4
|
+
|
|
5
|
+
crewswarm is an open-source AI workspace for software development. It combines multi-agent orchestration, project-aware memory, local tool execution, chat surfaces, and editor/MCP integrations into one stack you can run yourself.
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://nodejs.org)
|
|
9
|
+
[](https://crewswarm.ai)
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## What crewswarm is
|
|
16
|
+
|
|
17
|
+
Most AI dev tools are just a chat box bolted onto an editor.
|
|
18
|
+
|
|
19
|
+
**crewswarm** is different:
|
|
20
|
+
|
|
21
|
+
- **Local-first** β run it on your own machine
|
|
22
|
+
- **Real execution** β agents write files, run commands, and operate on actual projects
|
|
23
|
+
- **Multi-agent** β planner, coder, QA, fixer, security, GitHub, and more
|
|
24
|
+
- **Persistent context** β memory and session history survive beyond one chat
|
|
25
|
+
- **Multiple control surfaces** β dashboard, CLI, Telegram, SwiftBar, MCP/editor integrations
|
|
26
|
+
- **Model-flexible** β use Groq, OpenAI, Anthropic, Gemini, Mistral, DeepSeek, xAI, Ollama, and more
|
|
27
|
+
|
|
28
|
+
It is built for:
|
|
29
|
+
- solo builders
|
|
30
|
+
- AI-native dev teams
|
|
31
|
+
- local-first users who do not want SaaS lock-in
|
|
32
|
+
- people building real software with agent workflows, not toy demos
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Why it matters
|
|
37
|
+
|
|
38
|
+
Most βagentβ tools still fake the important part.
|
|
39
|
+
|
|
40
|
+
They can talk. They can plan. They can look clever.
|
|
41
|
+
|
|
42
|
+
Then they fall apart when it is time to:
|
|
43
|
+
- write real files
|
|
44
|
+
- work across multiple steps
|
|
45
|
+
- keep project memory
|
|
46
|
+
- coordinate multiple specialists
|
|
47
|
+
- run locally without disappearing into someone elseβs cloud
|
|
48
|
+
|
|
49
|
+
crewswarm is built to handle actual execution.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
### Requirements
|
|
56
|
+
|
|
57
|
+
- Node.js 20+
|
|
58
|
+
- At least one LLM provider key for best results
|
|
59
|
+
- Groq is the fastest free starting point: [console.groq.com](https://console.groq.com)
|
|
60
|
+
|
|
61
|
+
### Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/crewswarm/crewswarm
|
|
65
|
+
cd crewswarm
|
|
66
|
+
bash install.sh
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Fresh machine shortcut:**
|
|
70
|
+
```bash
|
|
71
|
+
bash <(curl -fsSL https://raw.githubusercontent.com/crewswarm/crewswarm/main/install.sh)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Start
|
|
75
|
+
```bash
|
|
76
|
+
npm run doctor
|
|
77
|
+
npm run restart-all
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then open:
|
|
81
|
+
`http://127.0.0.1:4319`
|
|
82
|
+
|
|
83
|
+
Add your provider key in the Providers tab, then go to Chat and start giving tasks.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### First example
|
|
88
|
+
|
|
89
|
+
In the dashboard chat, type:
|
|
90
|
+
> Build a REST API for user authentication with JWT and tests
|
|
91
|
+
|
|
92
|
+
**crewswarm will:**
|
|
93
|
+
- route the request through `crew-lead`
|
|
94
|
+
- break it down through `crew-pm`
|
|
95
|
+
- dispatch implementation to the right coding agent
|
|
96
|
+
- run QA / validation
|
|
97
|
+
- optionally hand off Git tasks
|
|
98
|
+
|
|
99
|
+
This is not simulated. It works against real files and your real local workspace.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### Headless / non-interactive install
|
|
104
|
+
|
|
105
|
+
For Cursor, Codex, CI, or remote shell setups:
|
|
106
|
+
```bash
|
|
107
|
+
CREWSWARM_SETUP_MCP=1 \
|
|
108
|
+
CREWSWARM_START_NOW=1 \
|
|
109
|
+
bash install.sh --non-interactive
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Optional flags:
|
|
113
|
+
- `CREWSWARM_BUILD_CREWCHAT=1`
|
|
114
|
+
- `CREWSWARM_SETUP_TELEGRAM=1`
|
|
115
|
+
- `CREWSWARM_SETUP_WHATSAPP=1`
|
|
116
|
+
- `CREWSWARM_ENABLE_AUTONOMOUS=1`
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Core capabilities
|
|
121
|
+
|
|
122
|
+
**Real tool execution**
|
|
123
|
+
Agents can write files, read files, create directories, run commands, and work inside a real project folder.
|
|
124
|
+
|
|
125
|
+
**PM-led orchestration**
|
|
126
|
+
Natural language requests are broken into structured tasks and routed to the right agent.
|
|
127
|
+
|
|
128
|
+
**Shared memory**
|
|
129
|
+
Project context persists through files like `brain.md`, `session-log.md`, `current-state.md`, and `orchestration-protocol.md`.
|
|
130
|
+
|
|
131
|
+
**Fault tolerance**
|
|
132
|
+
Retries, escalation to fixer agents, task leases, and dead-letter replay support are built in.
|
|
133
|
+
|
|
134
|
+
**Command approval gate**
|
|
135
|
+
Potentially risky shell commands require approval before execution.
|
|
136
|
+
|
|
137
|
+
**Multi-engine support**
|
|
138
|
+
Route work through different engines and environments, including Codex, Claude Code, Cursor, Gemini, OpenCode, and `crew-cli`.
|
|
139
|
+
|
|
140
|
+
**Multiple control surfaces**
|
|
141
|
+
Use crewswarm from the web dashboard, CLI, Telegram, macOS SwiftBar, or MCP/editor integrations.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Why crewswarm vs other frameworks
|
|
146
|
+
|
|
147
|
+
| Feature | crewswarm | LangChain / LangGraph | AutoGen | CrewAI |
|
|
148
|
+
|---|---|---|---|---|
|
|
149
|
+
| Real file writes | β
| β οΈ | β οΈ | β οΈ |
|
|
150
|
+
| PM-led planning | β
| β | β | β οΈ |
|
|
151
|
+
| Persistent memory | β
| β οΈ | β | β οΈ |
|
|
152
|
+
| Local-first | β
| β οΈ | β οΈ | β οΈ |
|
|
153
|
+
| Built-in dashboard | β
| β | β | β |
|
|
154
|
+
| Telegram / messaging bridges | β
| β | β | β |
|
|
155
|
+
| Easy local startup | β
| β οΈ | β οΈ | β οΈ |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Main components
|
|
160
|
+
|
|
161
|
+
| Component | Purpose |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `crew-lead` | conversational command layer and dispatcher |
|
|
164
|
+
| `crew-pm` | planning, task breakdown, roadmap management |
|
|
165
|
+
| `crew-coder` | implementation |
|
|
166
|
+
| `crew-qa` | testing and validation |
|
|
167
|
+
| `crew-fixer` | debugging and repair |
|
|
168
|
+
| `crew-security` | security review |
|
|
169
|
+
| `crew-github` | Git and repo actions |
|
|
170
|
+
| `dashboard` | browser-based control surface |
|
|
171
|
+
| `crew-cli` | command-line interface |
|
|
172
|
+
| `crew-scribe` | memory and task summarization |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Architecture
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Dashboard / Vibe / crew-cli / Telegram / SwiftBar / MCP
|
|
180
|
+
|
|
|
181
|
+
crew-lead
|
|
182
|
+
|
|
|
183
|
+
RT Bus
|
|
184
|
+
|
|
|
185
|
+
-----------------------------------
|
|
186
|
+
| | | | |
|
|
187
|
+
crew-pm coder qa fixer github
|
|
188
|
+
|
|
|
189
|
+
local tools + models
|
|
190
|
+
|
|
|
191
|
+
real files, commands, memory
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Commands
|
|
197
|
+
|
|
198
|
+
- **Preflight:** `npm run doctor`
|
|
199
|
+
- **Start the stack:** `npm run restart-all`
|
|
200
|
+
- **Launch Dashboard only:** `npm run dashboard`
|
|
201
|
+
- **Run CLI task:** `crew exec "Build a REST API with JWT auth and tests"`
|
|
202
|
+
- **Static smoke** (no services): `npm run smoke:static`
|
|
203
|
+
- **Live smoke** (stack must be running): `npm run smoke`
|
|
204
|
+
- **Health check:** `npm run health`
|
|
205
|
+
- **Release preflight:** `npm run release:check`
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Configuration
|
|
210
|
+
|
|
211
|
+
crewswarm stores config under your local `~/.crewswarm` directory.
|
|
212
|
+
|
|
213
|
+
Typical settings include provider API keys, agent model assignments, RT auth token, output path, and command allowlist.
|
|
214
|
+
|
|
215
|
+
The easiest way to manage config is through the dashboard.
|
|
216
|
+
|
|
217
|
+
**Example agent config**
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"agents": [
|
|
221
|
+
{ "id": "crew-pm", "model": "perplexity/sonar-pro" },
|
|
222
|
+
{ "id": "crew-coder", "model": "anthropic/claude-sonnet-4-20250514" },
|
|
223
|
+
{ "id": "crew-qa", "model": "groq/llama-3.3-70b-versatile" }
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Deployment
|
|
231
|
+
|
|
232
|
+
crewswarm is designed for local-first deployment but supports production containerization and cloud deployment. The system runs as a collection of Node.js services coordinated through an RT (realtime) bus, with optional web dashboard, CLI, and messaging bridge interfaces.
|
|
233
|
+
|
|
234
|
+
**Environment Configuration**
|
|
235
|
+
|
|
236
|
+
Production deployments require proper environment variable management. Store sensitive credentials in `.env` files and exclude them from version control using `.gitignore`. At minimum, configure one LLM provider API key (`GROQ_API_KEY`, `OPENAI_API_KEY`, or `ANTHROPIC_API_KEY`). The RT bus requires `RT_PORT` (default 4319) and `RT_AUTH_TOKEN` for secure inter-service communication. Dashboard configuration uses `VITE_RT_URL` and `VITE_RT_AUTH_TOKEN` to connect to the RT bus. Optional variables include `CREWSWARM_OUTPUT_PATH` for task outputs and `CREWSWARM_WORKSPACE` for project directories.
|
|
237
|
+
|
|
238
|
+
Generate cryptographically secure tokens for production:
|
|
239
|
+
```bash
|
|
240
|
+
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Additional configuration resides in `~/.crewswarm/config.json`, including provider credentials, agent-to-model assignments, command approval settings, and allowlists for shell command execution.
|
|
244
|
+
|
|
245
|
+
**Docker Support**
|
|
246
|
+
|
|
247
|
+
All crewswarm components support Docker containerization. Use multi-stage Dockerfiles to separate build dependencies from runtime artifacts, reducing final image size. A proper `.dockerignore` should exclude `node_modules/`, `.git/`, `.env` files, build artifacts, logs, and IDE configuration. Configure services using environment variables rather than hardcoded values, enabling 12-factor app compliance.
|
|
248
|
+
|
|
249
|
+
For the RT bus and Node services, expose only necessary ports (typically 4319 for RT bus, 8080 for dashboard). Use `docker-compose.yml` for local development and multi-container orchestration, or Kubernetes manifests for production clusters. Health checks ensure container orchestrators can detect and restart failed services.
|
|
250
|
+
|
|
251
|
+
Example minimal `.dockerignore`:
|
|
252
|
+
```
|
|
253
|
+
node_modules/
|
|
254
|
+
.git/
|
|
255
|
+
.env
|
|
256
|
+
*.log
|
|
257
|
+
dist/
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Production Infrastructure**
|
|
261
|
+
|
|
262
|
+
Production deployments benefit from process managers like PM2 or systemd for automatic restarts and clustering. Configure a reverse proxy (nginx, Caddy, Traefik) in front of services to handle TLS termination, load balancing, and request routing. Enable HTTPS using Let's Encrypt certificates for external-facing deployments.
|
|
263
|
+
|
|
264
|
+
Implement comprehensive monitoring using Prometheus for metrics collection and Grafana for visualization. Structure logs as JSON for easier aggregation in ELK stack (Elasticsearch, Logstash, Kibana) or similar log management platforms. Key metrics include task throughput, error rates, agent response times, and system resource utilization.
|
|
265
|
+
|
|
266
|
+
Security considerations for production:
|
|
267
|
+
- Enable command approval gates to review shell commands before execution
|
|
268
|
+
- Restrict RT bus port access via firewall rules
|
|
269
|
+
- Rotate API keys and auth tokens regularly
|
|
270
|
+
- Run services with minimal required permissions
|
|
271
|
+
- Implement rate limiting on public endpoints
|
|
272
|
+
- Regular dependency updates for security patches
|
|
273
|
+
|
|
274
|
+
For comprehensive deployment instructions including Docker examples, Kubernetes manifests, nginx configuration, monitoring setup, and troubleshooting, see **[DEPLOYMENT.md](DEPLOYMENT.md)**.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Project structure
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
crewswarm/
|
|
282
|
+
βββ crew-lead.mjs
|
|
283
|
+
βββ crew-cli/
|
|
284
|
+
βββ gateway-bridge.mjs
|
|
285
|
+
βββ telegram-bridge.mjs
|
|
286
|
+
βββ pm-loop.mjs
|
|
287
|
+
βββ unified-orchestrator.mjs
|
|
288
|
+
βββ phased-orchestrator.mjs
|
|
289
|
+
βββ continuous-build.mjs
|
|
290
|
+
βββ scripts/
|
|
291
|
+
βββ memory/
|
|
292
|
+
βββ docs/
|
|
293
|
+
βββ contrib/swiftbar/
|
|
294
|
+
βββ website/
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Docs
|
|
300
|
+
|
|
301
|
+
- `docs/CANONICAL/README.md`
|
|
302
|
+
- `docs/ARCHITECTURE.md`
|
|
303
|
+
- `docs/ORCHESTRATOR-GUIDE.md`
|
|
304
|
+
- `docs/SETUP-NEW-AGENTS.md`
|
|
305
|
+
- `docs/MODEL-RECOMMENDATIONS.md`
|
|
306
|
+
- `docs/TROUBLESHOOTING.md`
|
|
307
|
+
|
|
308
|
+
## Related repos
|
|
309
|
+
|
|
310
|
+
- `crew-cli` β standalone CLI for task execution and orchestration
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as e,a as t,g as n}from"./core-utils-CAVnDoe1.js";let o=!1;function a(){var n;const o=t.chatActiveProjectId;if(!o||"general"===o)return void e("Search requires an active project",!0);const a=document.getElementById("searchModal");a&&(a.style.display="flex",null==(n=document.getElementById("searchInput"))||n.focus())}function s(){const e=document.getElementById("searchModal");e&&(e.style.display="none")}async function r(){var o,a,s,r;const l=t.chatActiveProjectId;if(!l||"general"===l)return void e("Search requires an active project",!0);const c=null==(a=null==(o=document.getElementById("searchInput"))?void 0:o.value)?void 0:a.trim();if(!c)return void e("Enter a search query",!0);const d=(null==(s=document.getElementById("searchCaseSensitive"))?void 0:s.checked)||!1,u=(null==(r=document.getElementById("searchSource"))?void 0:r.value)||"",p=document.getElementById("searchResults");if(p){p.innerHTML='<div style="text-align:center;padding:20px;">Searching...</div>';try{let t=`/api/crew-lead/search-project-messages?projectId=${encodeURIComponent(l)}&q=${encodeURIComponent(c)}`;d&&(t+="&caseSensitive=true"),u&&(t+=`&source=${encodeURIComponent(u)}`);const o=await n(t);if(!o.ok)return void(p.innerHTML=`<div style="color:var(--red);padding:20px;">Error: ${i(o.error)}</div>`);if(0===o.results.length)return void(p.innerHTML='<div style="text-align:center;color:var(--text-3);padding:20px;">No results found</div>');const a={dashboard:"π»",cli:"β‘","sub-agent":"π·",agent:"π€"};let s=`<div style="margin-bottom:12px;font-weight:600;color:var(--text-2);">${o.results.length} results</div>`;for(const e of o.results){const t=a[e.source]||"π",n=e.agent?` [${e.agent}]`:"",o=new Date(e.ts).toLocaleString();s+=`\n <div style="border:1px solid var(--border);border-radius:6px;padding:12px;margin-bottom:8px;background:var(--bg-card2);">\n <div style="font-size:11px;color:var(--text-3);margin-bottom:6px;">\n ${t} <strong>${e.source}</strong>${n} Β· ${o}\n </div>\n <div style="font-size:13px;color:var(--text-1);">\n ${i(e.snippet)}\n </div>\n </div>\n `}p.innerHTML=s,e(`Found ${o.results.length} results`)}catch(g){console.error("Search failed:",g),p.innerHTML=`<div style="color:var(--red);padding:20px;">Search failed: ${i(g.message)}</div>`}}}function i(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function l(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b/i.test(t)||(!!/^>\s*(build|run|eval|install|pack|starting|sync|watch|plan)\b.*\/[\w.-]+/i.test(t)||(!!/^>\s*[^\n]+[\u00B7\u2022\u22C5\u2027\u30FBβ§β
]\s*\S/u.test(t)||!!/^[βββ\-]{3,}$/.test(t))))}function c(e,t){if("opencode"!==e&&"antigravity"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!l(e)).join("\n"):n}function d(e){const t=(n=String(e||"").replace(/\r/g,""),String(n||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")).trim();var n;return!t||(!!/^YOLO mode is enabled/i.test(t)||(!!/All tool calls will be automatically approved/i.test(t)||(!!/Loaded cached credentials/i.test(t)||(!!/^Using bundled/i.test(t)||(!!/^Authenticated via/i.test(t)||!!/^OpenTelemetry/i.test(t))))))}function u(e,t){if("gemini"!==e&&"gemini-cli"!==e)return String(t??"");const n=String(t??"");return n?n.split("\n").filter(e=>!d(e)).join("\n"):n}function p(e){return String(e||"").replace(/\r$/,"")}function g(e,t){const n=p(t);return!n.trim()||(!!/rmcp::/i.test(n)||(!!/error decoding response body.*initialized notification/i.test(n)||(!("codex"!==e||!/worker quit with fatal/i.test(n)||!/rmcp|mcp/i.test(n))||!!("codex"===e&&/\/mcp/i.test(n)&&/127\.0\.0\.1:\d+|localhost:\d+/i.test(n)&&/Connection refused|ConnectError|Transport channel closed|tcp connect error/i.test(n)))))}function m(e){return String(e||"").replace(/\u001b\[[\d;?]*[ -/]*[@-~]/g,"").replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g,"")}function h(e){const t=String(e||"");let n=0;return/SecItemCopyMatching|keychain|Keychain/i.test(t)&&(n+=100),/ERROR:\s|^ERROR\s|error:\s|FATAL|fatal|panic/i.test(t)&&(n+=45),/authentication|unauthorized|\b401\b|\b403\b|not logged in/i.test(t)&&(n+=30),/ENOTFOUND|ECONNREFUSED|ECONNRESET|certificate|TLS|SSL/i.test(t)&&(n+=25),/command not found|No such file|ENOENT/i.test(t)&&(n+=20),n}function f(e,t){const n=String(e||"").split("\n"),o=[];for(const r of n){if(g(t,r))continue;const e=m(p(r)).trim();e&&o.push(e)}if(!o.length)return"";let a=o[0],s=h(a);for(const r of o){const e=h(r);e>s&&(s=e,a=r)}return 0===s&&o.length>4?`${o[0]} (${o.length} lines)`:a}function y(e){var t,n;const{postJSON:o,getJSON:a,appendChatBubble:s,showNotification:r,state:i,getChatSessionId:l,getChatActiveProjectId:d,getCrewLeadInfo:h,appendRoadmapCard:y,getLastAppendedAssistantContent:v,setLastAppendedAssistantContent:x,setLastAppendedUserContent:b,setLastSentContent:w}=e,I="crewswarm_passthrough_log";function C(){var e;const t=document.getElementById("chatProjectSelect"),n=String((null==t?void 0:t.value)||"").trim(),o=document.querySelector("#chatProjectTabs [data-project-id].active"),a=String((null==(e=null==o?void 0:o.dataset)?void 0:e.projectId)||"").trim(),s=n&&"undefined"!==n?n:a&&"undefined"!==a?a:d()||i.chatActiveProjectId||"general";i.chatActiveProjectId=s;try{localStorage.setItem("crewswarm_chat_active_project_id",s)}catch{}return s}const E=[{id:"RESET",label:"Clear session history and start fresh",template:""},{id:"STOP",label:"Cancel all running pipelines (agents keep running)",template:""},{id:"KILL",label:"Kill all pipelines + terminate all agent bridges",template:""},{id:"SEARCH_HISTORY",label:"Search long-term chat history by keyword",template:"your search terms"},{id:"DISPATCH",label:"Dispatch task to an agent",template:'{"agent":"crew-coder","task":"Your task here"}'},{id:"PIPELINE",label:"Multi-step pipeline (waves of agents)",template:'[{"wave":1,"agent":"crew-coder","task":"..."},{"wave":2,"agent":"crew-qa","task":"..."}]'},{id:"PROMPT",label:"Append or set agent system prompt",template:'{"agent":"crew-lead","append":"Your new rule here"}'},{id:"SKILL",label:"Run a skill by name",template:'skillName {"param":"value"}'},{id:"SERVICE",label:"Restart/stop a service or agent",template:"restart crew-coder"},{id:"READ_FILE",label:"Read a file and get its contents",template:"/path/to/file"},{id:"RUN_CMD",label:"Run a shell command",template:"ls -la /home/user/CrewSwarm"},{id:"WEB_SEARCH",label:"Search the web (Perplexity)",template:"your search query"},{id:"WEB_FETCH",label:"Fetch a webpage or URL",template:"https://example.com"},{id:"PROJECT",label:"Draft a new project roadmap",template:'{"name":"MyApp","description":"...","outputDir":"/path/to/dir"}'},{id:"BRAIN",label:"Append a fact to brain.md",template:"crew-lead: fact to remember"},{id:"TOOLS",label:"Grant/revoke tools for an agent",template:'{"agent":"crew-qa","allow":["read_file","write_file"]}'},{id:"CREATE_AGENT",label:"Create a dynamic agent",template:'{"id":"crew-ml","role":"coder","description":"ML specialist"}'},{id:"REMOVE_AGENT",label:"Remove a dynamic agent",template:"crew-ml"},{id:"DEFINE_SKILL",label:"Define a new skill (then @@END_SKILL)",template:'skillName\\n{"description":"...","url":"..."}'},{id:"DEFINE_WORKFLOW",label:"Save a workflow for cron",template:'name\\n[{"agent":"crew-copywriter","task":"..."}]'}];let S=0;const T=[];let L=[],k=0;async function $(e=!1){const t=Date.now();if(!e&&L.length&&t-k<3e4)return L;const n=await a("/api/agents-config");return L=(n.agents||[]).filter(e=>e.id&&"crew-lead"!==e.id).sort((e,t)=>e.id.localeCompare(t.id)),k=t,L}async function A(){var e,t;const n=++S,o=()=>n!==S,r=document.getElementById("chatMessages");r&&(r.dataset.historyLoading="true");try{const n=d(),r=n&&"undefined"!==n?n:"general";if(console.log("π [LOAD HISTORY] =================="),console.log("π [LOAD HISTORY] START - projectId:",n),console.log("π [LOAD HISTORY] state.chatActiveProjectId:",i.chatActiveProjectId),console.log("π [LOAD HISTORY] URL hash:",window.location.hash),r){console.log("π [LOAD HISTORY] Loading unified project messages (all sources)"),console.log("π [LOAD HISTORY] ProjectId:",n);try{const t=`/api/crew-lead/project-messages?projectId=${encodeURIComponent(r)}&limit=250`;console.log("π [LOAD HISTORY] Fetching:",t);const n=await a(t);if(o())return;console.log("π [LOAD HISTORY] Unified response:",{ok:n.ok,messagesCount:(null==(e=n.messages)?void 0:e.length)||0,sources:n.messages?[...new Set(n.messages.map(e=>e.source))]:[]});const i=document.getElementById("chatMessages");if(!i)return void console.error("π [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(i.innerHTML="",i.dataset.historyLoaded="false",x(""),b(""),n.messages&&n.messages.length>0){const e={dashboard:"π»",cli:"β‘",agent:"π€","sub-agent":"π·"};let t=new Map;try{const e=await a("/api/agents-config");t=new Map(((null==e?void 0:e.agents)||[]).map(e=>[e.id,e]))}catch{}if(o())return;const r=n.messages;console.log("π [LOAD HISTORY] Appending",r.length,"unified messages (chunked rAF)...");const l=32;if(await new Promise(n=>{let a=0;const i=()=>{var c,d,u,p,g,m,h,f,y,v;if(o())return void n();const w=Math.min(a+l,r.length);for(;a<w;a++){if(o())return void n();const i=r[a],l=i.agent||(null==(c=i.metadata)?void 0:c.agentId)||null,w=l?t.get(l):null,I=(null==(d=i.metadata)?void 0:d.agentEmoji)||(null==w?void 0:w.emoji)||e[i.source]||"π",C=(null==(u=i.metadata)?void 0:u.agentName)||(null==w?void 0:w.name)||l||null,E=new Date(i.ts).toLocaleTimeString(),S={emoji:I,source:i.source,agent:C,agentName:C,agentId:l,targetAgent:(null==(p=i.metadata)?void 0:p.targetAgent)||(null==(g=i.metadata)?void 0:g.agentId)||null,engine:(null==(m=i.metadata)?void 0:m.engine)||(null==(h=i.metadata)?void 0:h.runtime)||(null==(f=i.metadata)?void 0:f.model)||null,timestamp:E};s("user"===i.role?"user":"assistant",i.content,null,null,null==(y=i.metadata)?void 0:y.model,null==(v=i.metadata)?void 0:v.engine,S),"assistant"===i.role&&x(i.content),"user"===i.role&&b(i.content)}a<r.length?requestAnimationFrame(i):n()};requestAnimationFrame(i)}),o())return;return console.log("π [LOAD HISTORY] β
Loaded unified view with all sources"),i.dataset.historyLoaded="true",void(i.scrollTop=i.scrollHeight)}return console.log("π [LOAD HISTORY] No messages in unified response (might be empty project)"),void(i.dataset.historyLoaded="true")}catch(l){console.error("π [LOAD HISTORY] β οΈ Unified view failed:",l),console.error("π [LOAD HISTORY] Error details:",{message:l.message,stack:l.stack});const e=document.getElementById("chatMessages");if(e){const t=document.createElement("div");t.style.cssText="padding:12px;margin:8px;background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);border-radius:8px;color:#ef4444;font-size:13px;",t.innerHTML="β οΈ <strong>crew-lead unavailable</strong> β Cannot load project message history.<br><small>Check that crew-lead is running: <code>node crew-lead.mjs</code></small>",e.appendChild(t)}console.log("π [LOAD HISTORY] Falling back to crew-lead-only history...")}}let c="/api/crew-lead/history?sessionId=owner";r&&"general"!==r&&(c+="&projectId="+encodeURIComponent(r)),console.log("π [LOAD HISTORY] Fetching crew-lead history:",c);const u=await a(c);if(o())return;if(console.log("π [LOAD HISTORY] Response:",{historyCount:(null==(t=u.history)?void 0:t.length)||0}),console.log("π [LOAD HISTORY] Response projectId:",u.projectId),u.history&&u.history.length>0){const e=u.history.filter(e=>"user"===e.role);e.length>0&&(console.log("π [LOAD HISTORY] First user msg:",e[0].content.slice(0,50)),console.log("π [LOAD HISTORY] Last user msg:",e[e.length-1].content.slice(0,50)))}const p=document.getElementById("chatMessages");if(!p)return void console.error("π [LOAD HISTORY] ERROR: chatMessages element not found!");if(o())return;if(console.log("π [LOAD HISTORY] Clearing chatMessages..."),p.innerHTML="",p.dataset.historyLoaded="false",x(""),b(""),u.history&&u.history.length){const e=u.history.slice(-50);console.log("π [LOAD HISTORY] Appending",e.length,"messages..."),e.forEach(e=>{o()||(s("user"===e.role?"user":"assistant",e.content),"assistant"===e.role&&x(e.content),"user"===e.role&&b(e.content))}),console.log("π [LOAD HISTORY] Appended",e.length,"messages")}else console.log("π [LOAD HISTORY] No history found");if(!u.history||0===u.history.length){const e=JSON.parse(localStorage.getItem(I)||"[]"),t=Date.now()-216e5,n=e.filter(e=>e.timestamp&&"number"==typeof e.timestamp&&e.timestamp>t&&e.text&&e.text.trim().length>0);n.length>0&&O(n),n.length!==e.length&&localStorage.setItem(I,JSON.stringify(n))}p.scrollTop=p.scrollHeight,p.dataset.historyLoaded="true"}catch(c){if(o())return;console.warn("Failed to load chat history:",c);const e=document.getElementById("chatMessages");e&&(e.dataset.historyLoaded="true")}finally{r&&(r.dataset.historyLoading="false"),T.splice(0).forEach(e=>{try{e()}catch{}})}}function O(e){const t=document.getElementById("chatMessages");if(!t||!e.length)return;const n={claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"};for(const o of e)if("user"===o.role)s("user",o.text);else{let e=String(o.text||"").split("\n").filter(e=>!g(o.engine,e)).join("\n").trim();e=c(o.engine,e),e=u(o.engine,e);const a=document.createElement("div");a.className="chat-bubble assistant",a.style.cssText="background:var(--surface-2);border-radius:10px;padding:12px 14px;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;font-family:monospace;font-size:12px;color:var(--text-2);";const s=document.createElement("div");s.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const r=o.exitCode??0;s.textContent=(n[o.engine]||o.engine)+" Β· direct passthrough "+(0===r?"β":"β ")+" (exit "+r+")";const i=document.createElement("div");i.textContent=e||o.text,a.appendChild(s),a.appendChild(i),t.appendChild(a)}}let R=null;async function M(){var e,t;const n=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=n.value.trim();if(!r)return;if(R)return R.abort(),R=null,n.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),void n.focus();const c=(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)||"",d=(null==(t=document.getElementById("chatAgentSelector"))?void 0:t.value)||"",u=document.getElementById("chatModeSelector"),p=(null==u?void 0:u.value)||"crew-lead";if(p.startsWith("cli:")){const e=p.replace("cli:","");return void(await B(r,e))}if("crew-lead"!==p)return void(await z(r,p));if(c)return void(await B(r,c));if(d)return void(await z(r,d));const g=await async function(e){const t=String(e||"").match(/^\s*@([a-zA-Z0-9_-]+)\b([\s\S]*)$/);if(!t)return null;const n=t[1];return n&&"crew-lead"!==n&&(await $()).some(e=>e.id===n)?{agentId:n,message:t[2].trim()||e.trim()}:null}(r);if(g)return void(await z(g.message,g.agentId));n.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),s("user",r),b(r),w(r),x("");const m="typing-"+Date.now(),f=document.createElement("div");f.id=m,f.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;";const I=h()||{emoji:"π§ ",name:"crew-lead"};f.textContent=I.emoji+" "+I.name+" is thinking...";const E=document.getElementById("chatMessages");E.appendChild(f),E.scrollTop=E.scrollHeight;const S=new AbortController;try{const e=C(),t=e&&i.projectsData[e],n=await o("/api/chat/unified",{mode:"crew-lead",message:r,sessionId:l(),projectId:e||"general",...(null==t?void 0:t.outputDir)?{projectDir:t.outputDir}:{}},S.signal);if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),!1===n.ok&&n.error?(s("assistant","β οΈ "+n.error),x("")):n.reply&&(v()||(s("assistant",n.reply),x(n.reply),E&&(E.scrollTop=E.scrollHeight))),n.dispatched){const e=Array.isArray(n.dispatched)?n.dispatched.map(e=>(null==e?void 0:e.agent)||(null==e?void 0:e.id)).filter(Boolean):[n.dispatched.agent].filter(Boolean),t=document.createElement("div");t.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.length&&(t.textContent="β‘ Dispatched to "+e.join(", "),E.appendChild(t))}n.pendingProject&&y(E,n.pendingProject),E.scrollTop=E.scrollHeight}catch(T){if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),"AbortError"===T.name)s("assistant","β οΈ Message cancelled"),x("");else{let e=T.message||String(T);try{const t=JSON.parse(e);t&&"string"==typeof t.error&&(e=t.error)}catch{}s("assistant","β οΈ Error: "+e),x("")}E.scrollTop=E.scrollHeight}finally{R=null,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),n.focus()}}function D(e,t,n,o){try{const a=JSON.parse(localStorage.getItem(I)||"[]");a.push({role:e,engine:t,text:n,exitCode:o,timestamp:Date.now()}),a.length>200&&a.splice(0,a.length-200),localStorage.setItem(I,JSON.stringify(a))}catch{}}let j=null;async function H(){var e;const t=document.getElementById("passthroughSessionIndicator");if(!t)return;const n=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!n)return void(t.style.display="none");const o=C(),s=o&&i.projectsData[o],r=(null==s?void 0:s.outputDir)||null,c=l()||"owner";try{const e=(await a("/api/passthrough-sessions")).sessions||{},o=r?`${n}:${r}:${c}`:null,i=o&&(e[o]||e[`${n}:${r}`]);t.style.display=i?"inline-block":"none",t.title=i?`Session active for ${(null==s?void 0:s.name)||(null==r?void 0:r.split("/").pop())||"this project"} β click to clear`:""}catch{t.style.display="none"}}async function B(e,t){var n;const o=document.getElementById("chatInput"),a=document.querySelector('[data-action="sendChat"]'),r=document.querySelector('[data-action="stopPassthrough"]'),d=document.getElementById("passthroughModel");if(j)return j.abort(),j=null,o.disabled=!1,a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),void o.focus();o.value="",a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),r&&(r.style.display="none"),s("user",e);const h=document.getElementById("chatMessages"),y=document.createElement("div");y.className="chat-bubble assistant",y.style.cssText="background:var(--surface-2);border-radius:10px;padding:12px 14px;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;font-family:monospace;font-size:12px;color:var(--text-2);";const v=document.createElement("div");v.style.cssText="font-size:11px;font-weight:700;color:var(--text-3);margin-bottom:6px;";const x=C(),b=x&&i.projectsData[x],w=(null==d?void 0:d.value)||"",I=w?` [${w}]`:"";v.textContent=({claude:"Claude Code",cursor:"Cursor CLI",opencode:"OpenCode",codex:"Codex CLI",gemini:"Gemini CLI","gemini-cli":"Gemini CLI","docker-sandbox":"Docker Sandbox","crew-cli":"Crew CLI"}[t]||t)+I+" Β· direct passthrough"+((null==b?void 0:b.outputDir)?" @ "+b.outputDir.split("/").pop():"");const E=document.createElement("div");y.appendChild(v),y.appendChild(E),h.appendChild(y),h.scrollTop=h.scrollHeight;const S=new AbortController,T=function(e){let t="";return{push(n){t+=String(n||"");const o=t.split("\n");t=o.pop()??"";const a=[];for(const t of o){if(g(e,t))continue;const n=m(p(t)).trimEnd();n&&a.push(n)}return a.length?`${a.join("\n")}\n`:""},flush(){const n=t;if(t="",!n)return"";if(g(e,n))return"";const o=m(p(n)).trimEnd();return o?`${o}\n`:""}}}(t);let L="",k=!1;try{const o=(null==b?void 0:b.outputDir)||void 0,a=(null==(n=document.getElementById("passthroughInjectHistory"))?void 0:n.checked)||!1,s={engine:t,message:e};o&&(s.projectDir=o),s.projectId=x||"general",s.sessionId=l(),a&&(s.injectHistory=!0),w&&(s.model=w);const r=await fetch("/api/chat/unified",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({mode:"cli",...s}),signal:S.signal});if(!r.ok)return void(E.textContent=`Error ${r.status}: ${await r.text()}`);const i=r.body.getReader(),d=new TextDecoder;let p="";for(;;){const{done:n,value:o}=await i.read();if(n)break;p+=d.decode(o,{stream:!0});const a=p.split("\n");p=a.pop()||"";for(const s of a)if(s.startsWith("data: "))try{const n=JSON.parse(s.slice(6));if("chunk"===n.type&&n.text){let e=c(t,n.text);e=u(t,e),e&&(k=!0,E.textContent+=e,h.scrollTop=h.scrollHeight)}else if("stderr"===n.type&&n.text){const e=T.push(n.text);if(e){L+=e;let n=c(t,e);n=u(t,n);n&&(!("opencode"===t||"antigravity"===t)||!k)&&(E.textContent+=n,h.scrollTop=h.scrollHeight)}}else if("done"===n.type){const o=T.flush();if(o){L+=o;let e=c(t,o);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(E.textContent+=e,h.scrollTop=h.scrollHeight)}const a=n.exitCode??0,s=0===a;v.textContent+=` ${s?"β":"β "} (exit ${a})`;const r=f(L,t);if(!s&&r&&!E.textContent.includes(r)){const e=document.createElement("div");e.style.cssText="font-size:11px;font-weight:600;color:var(--danger, #f87171);margin-top:8px;white-space:pre-wrap;word-break:break-word;",e.textContent=`β³ ${r}`,y.appendChild(e),h.scrollTop=h.scrollHeight}D("user",t,e,null),D("engine",t,E.textContent,a)}}catch{}}const g=T.flush();if(g){L+=g;let e=c(t,g);e=u(t,e);!e||("opencode"===t||"antigravity"===t)&&k||(E.textContent+=e,h.scrollTop=h.scrollHeight)}}catch($){"AbortError"===$.name?(v.textContent+=" β (killed)",E.textContent+=E.textContent?"\n\n[stopped]":"[stopped]"):E.textContent="Error: "+$.message}finally{j=null,r&&(r.style.display="none"),a&&(a.disabled=!1,a.textContent="Send",a.className="btn-green"),o.focus(),H()}}let P=null,N=[];async function F(e,t){let n;if(e instanceof File)n=e;else{const e=document.getElementById("imageUpload");if(!e.files||!e.files[0])return;n=e.files[0],e.value=""}const a=n.name,r=n.type;(n.size/1024).toFixed(1);const i=r.startsWith("image/"),l="application/pdf"===r,c=r.includes("spreadsheet")||r.includes("excel")||a.match(/\.(xlsx?|csv)$/i),d=r.includes("document")||a.match(/\.(docx?|txt|md)$/i);let u="π";i?u="π·":l?u="π":c?u="π":d&&(u="π");const p=document.getElementById("chatInput"),g=p?p.value.trim():"",m=t||g||(i?"Describe this image in detail. What do you see?":`Analyze this ${a} file`);s("user",`${u} [Attached: ${a}] ${g?`\n\n${g}`:""}`),s("assistant",`π Analyzing ${i?"image":"file"}...`);try{const e=await function(e){return new Promise((t,n)=>{const o=new FileReader;o.onload=()=>t(o.result),o.onerror=n,o.readAsDataURL(e)})}(n),t=await o("/api/analyze-image",{image:e,prompt:m,fileName:a,fileType:r});t.ok?(s("assistant",`**${i?"Image":"File"} Analysis:**\n\n${t.result}`),p&&(p.value=`[Attached: ${a}]\n\n${t.result}\n\n`,p.focus())):s("assistant",`β οΈ Analysis failed: ${t.error}`)}catch(h){s("assistant",`β οΈ Analysis error: ${h.message}`)}p&&g&&(p.value="")}async function z(e,t){const n=document.getElementById("chatInput");document.querySelector('[data-action="sendChat"]');const r=document.getElementById("chatMessages");n.value="",s("user",e),b(e),w(e);let i={emoji:"π€",name:t,model:""};try{const e=((await a("/api/agents-config")).agents||[]).find(e=>e.id===t);e&&(i={emoji:e.emoji||"π€",name:e.name||t,model:Y(e)})}catch(u){console.warn("Could not fetch agent info:",u)}const c="typing-"+Date.now(),d=document.createElement("div");d.id=c,d.style.cssText="font-size:12px;color:var(--text-3);padding:4px 6px;",d.textContent=`${i.emoji} ${i.name} is thinking...`,r.appendChild(d),r.scrollTop=r.scrollHeight;try{const n=C(),a=await o("/api/chat/unified",{mode:"agent",agentId:t,message:e,sessionId:`dashboard-chat-${t}-${l()}`,projectId:n||"general"});if(document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),a.error)return U(i,"β οΈ "+a.error,r),void x("");if(a.reply&&(U(i,a.reply,r),x(a.reply)),a.cliInvoked){const e=document.createElement("div");e.style.cssText="font-size:11px;color:var(--text-3);text-align:center;padding:4px;",e.textContent=`β‘ Executing ${a.cliInvoked}... (check process status)`,r.appendChild(e)}r.scrollTop=r.scrollHeight}catch(u){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove()),U(i,"β οΈ Error: "+u.message,r),x("")}}function U(e,t,n){const o=document.createElement("div");o.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;";const a=document.createElement("div");if(a.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;align-items:center;gap:6px;",a.textContent=`${e.emoji} ${e.name}`,e.model){const t=document.createElement("span");t.title="Primary model",t.style.cssText="font-size:10px;padding:1px 6px;border-radius:999px;background:rgba(52,211,153,0.1);color:#34d399;border:1px solid rgba(52,211,153,0.2);cursor:default;";const[n,...o]=e.model.split("/");t.textContent=o.join("/")||e.model,a.appendChild(t)}const s=document.createElement("div");s.style.cssText="max-width:80%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);white-space:pre-wrap;word-break:break-word;line-height:1.5;border:1px solid var(--border);",s.textContent=t,o.appendChild(a),o.appendChild(s),n.appendChild(o)}function Y(e){const{route:t,model:n}=function(e){return e.useCursorCli?{route:"cursor",model:e.cursorCliModel||"auto"}:e.useClaudeCode?{route:"claude",model:e.claudeCodeModel||"auto"}:e.useCodex?{route:"codex",model:e.codexModel||"auto"}:e.useGeminiCli?{route:"gemini",model:e.geminiCliModel||"auto"}:e.useCrewCLI?{route:"crew-cli",model:e.crewCliModel||"auto"}:!0===e.useOpenCode?{route:"opencode",model:e.opencodeModel||e.model||"default"}:{route:"llm",model:e.model||"no model"}}(e);return"llm"===t?n:`${t}:${n}`}[document.getElementById("chatInput"),document.getElementById("chatMessages")].forEach(e=>{e&&(e.addEventListener("dragover",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="2px dashed var(--accent, #3b82f6)"}),e.addEventListener("dragleave",t=>{t.preventDefault(),t.stopPropagation(),e.style.outline=""}),e.addEventListener("drop",async t=>{t.preventDefault(),t.stopPropagation(),e.style.outline="";const n=t.dataTransfer.files;if(n&&n.length>0){const e=n[0];await F(e)}}))});let q=0;async function _(e=!1){if(!e&&Date.now()-q<5e3)return;const t=document.getElementById("chatModeSelector"),n=document.getElementById("agentsOptgroup");if(t&&n)try{const e=(await a("/api/agents-config")).agents||[],t=new Set(["crew-lead","orchestrator","crew-orchestrator","crew-pm-cli","crew-pm-frontend","crew-pm-core"]);n.innerHTML="",e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const o=e.emoji||"π€",a=Y(e);t.textContent=`${o} ${e.id} β ${a}`,n.appendChild(t)}),q=Date.now()}catch(s){console.error("Failed to load agents for unified mode selector:",s)}const o=document.getElementById("chatAgentSelector");if(o)try{const e=(await a("/api/agents-config")).agents||[];o.innerHTML='<option value="">π§ Crew Lead (default)</option>';const t=new Set(["crew-lead","orchestrator","crew-orchestrator"]);e.filter(e=>!t.has(e.id)).sort((e,t)=>e.id.localeCompare(t.id)).forEach(e=>{const t=document.createElement("option");t.value=e.id;const n=Y(e);t.textContent=`${e.id} β ${n}`,o.appendChild(t)})}catch(s){console.error("Failed to load agents for chat selector:",s)}}_(),null==(t=document.getElementById("chatModeSelector"))||t.addEventListener("focus",()=>{_(!0)});let K=null;function J(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const n=Math.floor(t/60);if(n<60)return`${n}m ${t%60}s`;return`${Math.floor(n/60)}h ${n%60}m`}return K&&clearInterval(K),K=setInterval(async()=>{var e;const t=document.getElementById("chatModeSelector"),n=(null==t?void 0:t.value)||"crew-lead";let o=null;if(n.startsWith("cli:")){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}if("crew-lead"!==n&&(o=n),o||(o=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value),!o){const e=document.getElementById("chatCLIProcessStatus");return void(e&&(e.style.display="none"))}try{const e=await a(`/api/cli-processes?agent=${o}`);!function(e){const t=document.getElementById("chatCLIProcessStatus");t&&(0!==e.length?(t.style.display="block",t.innerHTML=e.map(e=>{const t=J(e.duration),n=J(e.idleFor);return`\n <div style="border-left:3px solid ${"running"===e.status?"#22c55e":"#f59e0b"};padding:8px 12px;background:var(--bg-card2);border-radius:6px;margin-bottom:8px;">\n <div style="display:flex;justify-content:space-between;margin-bottom:6px;">\n <span style="font-weight:600;font-family:monospace;font-size:13px;">${"running"===e.status?"β‘":"βΈοΈ"} ${e.cli}</span>\n <span style="text-transform:uppercase;font-size:11px;font-weight:700;color:var(--text-3);">${e.status}</span>\n </div>\n <div style="font-size:12px;color:var(--text-2);line-height:1.5;">\n <div>Task: ${(e.task||"unknown").slice(0,80)}</div>\n <div>Duration: ${t} | Idle: ${n} | Lines: ${e.outputLines||0}</div>\n </div>\n </div>\n `}).join("")):t.style.display="none")}(e.processes||[])}catch(s){console.error("Failed to load CLI process status:",s)}},3e3),null==(n=document.getElementById("chatAgentSelector"))||n.addEventListener("change",()=>{var e;const t=null==(e=document.getElementById("chatAgentSelector"))?void 0:e.value;t&&r(`Switched to ${t} - messages go directly to this agent's LLM`,"success")}),{loadChatHistory:A,waitForChatHistoryIdle:function(){const e=document.getElementById("chatMessages");return e&&"true"===e.dataset.historyLoading?new Promise(e=>{T.push(e)}):Promise.resolve()},chatAtAtInput:function(){const e=document.getElementById("chatInput"),t=document.getElementById("chatAtAtMenu"),n=document.getElementById("chatAtAtTemplate");if(e&&t&&n)try{const o=e.value,a=e.selectionStart,s=o.slice(0,a),r=s.match(/(^|\s)@([a-zA-Z0-9_-]*)$/);if(r&&s.lastIndexOf("@@")!==s.length-r[0].length)return void $().then(s=>{const i=(r[2]||"").toLowerCase(),l=s.filter(e=>e.id.toLowerCase().includes(i)).slice(0,8);if(!l.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.dataset.mode="mention",t.innerHTML="",l.forEach(s=>{const i=document.createElement("div");i.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",i.onmouseenter=function(){i.style.background="var(--bg-hover)"},i.onmouseleave=function(){i.style.background=""},i.innerHTML=`<span style="color:var(--accent);font-weight:600;">@${s.id}</span> <span style="color:var(--text-3);">${s.name||s.role||"agent"}</span>`,i.onclick=function(){const i=a-r[0].length+r[1].length,l=`@${s.id} `;e.value=o.slice(0,i)+l+o.slice(a),e.selectionStart=e.selectionEnd=i+l.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=`Mention target: @${s.id}`},t.appendChild(i)}),n.style.display="block",n.textContent=i?`Matching agents for @${i}`:"Type an agent name, e.g. @crew-coder"}).catch(()=>{t.style.display="none",n.style.display="none"});const i=s.lastIndexOf("@@");if(-1===i)return t.style.display="none",void(n.style.display="none");const l=s.slice(i+2);if(/\s/.test(l))return t.style.display="none",void(n.style.display="none");const c=l.toUpperCase(),d=E.filter(e=>0===e.id.indexOf(c));if(0===d.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.style.visibility="visible",t.dataset.mode="atat",t.innerHTML="",d.forEach(s=>{const r=document.createElement("div");r.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",r.onmouseenter=function(){r.style.background="var(--bg-hover)"},r.onmouseleave=function(){r.style.background=""},r.innerHTML='<span style="color:var(--accent);font-weight:600;">@@'+s.id+'</span> <span style="color:var(--text-3);">'+s.label+"</span>",r.onclick=function(){const r="@@"+s.id+(s.template?" "+s.template:"");e.value=o.slice(0,i)+r+o.slice(a),e.selectionStart=e.selectionEnd=i+r.length,e.focus(),t.style.display="none",n.style.display="block",n.textContent=("PROMPT"===s.id?"Full line to send: @@PROMPT ":"Template: ")+(s.template?s.template:"")},t.appendChild(r)});const u=d.find(e=>e.id===c);u?(n.style.display="block",n.textContent=("PROMPT"===u.id?"Full line: @@PROMPT ":"Template: ")+(u.template||"")):n.style.display="none"}catch(o){"undefined"!=typeof console&&console.warn("chatAtAtInput",o)}},chatKeydown:function(e){const t=document.getElementById("chatAtAtMenu");if(t&&"block"===t.style.display&&("Enter"===e.key||"Tab"===e.key)){const n=t.firstElementChild;if(n)return e.preventDefault(),void n.click()}"Enter"!==e.key||e.shiftKey||(e.preventDefault(),M()),!t||"block"!==t.style.display||"Escape"!==e.key&&"Tab"!==e.key||(t.style.display="none")},sendChat:M,sendDirectAgent:z,loadChatAgentSelector:_,clearChatHistory:async function(){if(!confirm("Clear chat history for this session?"))return;const e=document.getElementById("chatMessages");e.innerHTML="",e.dataset.historyLoaded="false",localStorage.removeItem(I),await o("/api/crew-lead/clear",{sessionId:l()}).catch(()=>{}),await A()},restorePassthroughLog:function(){var e;try{const t=JSON.parse(localStorage.getItem(I)||"[]");if(!t.length)return;const n=document.getElementById("chatMessages");if(!n)return;(null==(e=document.getElementById("passthroughEngine"))?void 0:e.value)&&0===n.children.length&&(O(t),n.scrollTop=n.scrollHeight)}catch{}},sendPassthrough:B,stopAll:async function(){if(confirm("Stop all running pipelines?"))try{await o("/api/crew-lead/chat",{message:"@@STOP",sessionId:l()}),r("βΉ Stop signal sent")}catch(e){r("Failed: "+e.message,!0)}},killAll:async function(){if(confirm("Kill all agents? Bridges must be restarted after."))try{await o("/api/crew-lead/chat",{message:"@@KILL",sessionId:l()}),r("β οΈ Kill signal sent")}catch(e){r("Failed: "+e.message,!0)}},killPassthrough:function(){j&&(j.abort(),j=null)},refreshSessionIndicator:H,clearPassthroughSession:async function(){var e;const t=null==(e=document.getElementById("passthroughEngine"))?void 0:e.value;if(!t)return;const n=C(),o=n&&i.projectsData[n],a=(null==o?void 0:o.outputDir)||null;if(!a)return;const s=`${t}:${a}:${l()||"owner"}`,c=`${t}:${a}`;try{await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(s)}`,{method:"DELETE"}),await fetch(`/api/passthrough-sessions?key=${encodeURIComponent(c)}`,{method:"DELETE"}),r("Session cleared β next message starts fresh"),H()}catch(d){r("Failed: "+d.message,!0)}},resetSendButton:function(){const e=document.querySelector('[data-action="sendChat"]');e&&(e.textContent="Send",e.className="btn-green",e.disabled=!1)},handleImageUpload:F,toggleVoiceRecording:async function(){const e=document.getElementById("recordVoiceBtn");if(P&&"inactive"!==P.state)P.stop(),e.textContent="π€",e.style.background="";else try{const t=await navigator.mediaDevices.getUserMedia({audio:!0});N=[],P=new MediaRecorder(t,{mimeType:"audio/webm"}),P.ondataavailable=e=>{e.data.size>0&&N.push(e.data)},P.onstop=async()=>{const e=new Blob(N,{type:"audio/webm"});t.getTracks().forEach(e=>e.stop()),s("user",`π€ [Voice message recorded - ${(e.size/1024).toFixed(0)} KB]`),s("assistant","π€ Transcribing voice...");try{const t=new FormData;t.append("audio",e,"voice.webm");const o=new AbortController,a=setTimeout(()=>o.abort(),6e4),r=await fetch("/api/transcribe-audio",{method:"POST",body:t,signal:o.signal});let i;clearTimeout(a);try{i=await r.json()}catch(n){return s("assistant",`β οΈ Transcription error: Server returned invalid response (${r.status})`),void(N=[])}if(i.ok&&i.transcription){s("assistant",`**Transcription:**\n\n"${i.transcription}"`);const e=document.getElementById("chatInput");e.value=i.transcription,e.focus()}else s("assistant",`β οΈ Transcription failed: ${i.error||"No result"}`)}catch(o){const e=o.message||String(o);s("assistant",`β οΈ Transcription error: ${e}${"Failed to fetch"===e?" (Is the dashboard running on port 4319? Try: npm run restart-dashboard)":""}`)}N=[]},P.start(),e.textContent="βΉοΈ",e.style.background="var(--red, #ef4444)",r("π€ Recording... Click again to stop")}catch(t){r("β οΈ Microphone access denied: "+t.message,!0)}}}}"undefined"!=typeof window&&(window.toggleUnifiedView=async function(){o=!o;const a=document.getElementById("unifiedViewToggle");o?(a.style.background="var(--accent)",a.style.color="#fff",a.textContent="π Unified β",e("Unified view enabled β showing all sources")):(a.style.background="",a.style.color="",a.textContent="π Unified View",e("Standard view restored")),await async function(){const a=t.chatActiveProjectId;if(a&&"general"!==a)if(o)try{const t=await n(`/api/crew-lead/project-messages?projectId=${encodeURIComponent(a)}&limit=100`);if(!t.ok)return console.error("Failed to load unified messages:",t.error),void e("Failed to load unified view",!0);const o=document.getElementById("chatMessages");if(!o)return;o.innerHTML="";const s={dashboard:"π»",cli:"β‘","sub-agent":"π·",agent:"π€"};for(const e of t.messages){const t=document.createElement("div");t.className=`chat-bubble ${e.role}`;const n=s[e.source]||"π",a=e.agent?` [${e.agent}]`:"",r=new Date(e.ts).toLocaleTimeString();t.innerHTML=`\n <div style="font-size:10px;color:var(--text-3);margin-bottom:4px;">\n ${n} <strong>${e.source}</strong>${a} Β· ${r}\n </div>\n <div style="white-space:pre-wrap;word-break:break-word;">${i(e.content)}</div>\n `,o.appendChild(t)}o.scrollTop=o.scrollHeight,e(`Loaded ${t.messages.length} messages from all sources`)}catch(s){console.error("Failed to load unified messages:",s),e("Failed to load unified view",!0)}else window.loadChatHistory&&await window.loadChatHistory()}()},window.openSearchModal=a,window.closeSearchModal=s,window.performSearch=r,window.exportMessages=async function(){const n=t.chatActiveProjectId;if(!n||"general"===n)return void e("Export requires an active project",!0);const o=await new Promise(e=>{const t=document.createElement("div");t.style.cssText="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:10001;display:flex;align-items:center;justify-content:center;",t.innerHTML='\n <div style="background:var(--bg-card);border-radius:12px;padding:24px;max-width:400px;">\n <h3 style="margin:0 0 16px 0;">Export Format</h3>\n <div style="display:flex;flex-direction:column;gap:8px;margin-bottom:16px;">\n <button class="export-format-btn btn-ghost" data-format="markdown" style="text-align:left;padding:12px;">\n π Markdown (.md) β Best for reading\n </button>\n <button class="export-format-btn btn-ghost" data-format="json" style="text-align:left;padding:12px;">\n π JSON β Full data with metadata\n </button>\n <button class="export-format-btn btn-ghost" data-format="csv" style="text-align:left;padding:12px;">\n π CSV β Spreadsheet compatible\n </button>\n <button class="export-format-btn btn-ghost" data-format="txt" style="text-align:left;padding:12px;">\n π Plain Text (.txt)\n </button>\n </div>\n <button onclick="this.closest(\'div\').parentElement.remove()" class="btn-ghost" style="width:100%;">Cancel</button>\n </div>\n ',document.body.appendChild(t),t.querySelectorAll(".export-format-btn").forEach(n=>{n.onclick=()=>{e(n.dataset.format),t.remove()}}),t.onclick=n=>{n.target===t&&(e(null),t.remove())}});if(o)try{e("Exporting...");const t=`/api/crew-lead/export-project-messages?projectId=${encodeURIComponent(n)}&format=${o}&includeMetadata=true`,a=document.createElement("a");a.href=t,a.download=`project-${n}.${"markdown"===o?"md":o}`,document.body.appendChild(a),a.click(),document.body.removeChild(a),e(`Exported as ${o.toUpperCase()}`)}catch(a){console.error("Export failed:",a),e("Export failed: "+a.message,!0)}}),"undefined"!=typeof window&&document.addEventListener("keydown",e=>{if((e.metaKey||e.ctrlKey)&&"k"===e.key){const n=t.chatActiveProjectId;n&&"general"!==n&&(e.preventDefault(),a())}if("Escape"===e.key){const e=document.getElementById("searchModal");e&&"none"!==e.style.display&&s()}"Enter"===e.key&&"searchInput"===e.target.id&&(e.preventDefault(),r())});export{y as i};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as e,u as o,a as t}from"./orchestration-Ca2DLWN-.js";let n="connected";function c(){["configChatModel","configRouterModel","configReasoningModel","configL2AModel","configL2BModel","configExecutionModel","configQAModel"].forEach(e=>{const o=document.getElementById(e);o&&"1"!==o.dataset.customBound&&(o.dataset.customBound="1",o.addEventListener("change",()=>function(e){if(!e||"__custom__"!==e.value)return;const o=e.dataset.previousValue||"",t=window.prompt("Enter exact model ID for this slot:",o),n=String(t||"").trim();if(!n)return void(e.value=o);let c=Array.from(e.options).find(e=>e.value===n);if(!c){c=document.createElement("option"),c.value=n,c.textContent=`${n} (custom)`;const o=Array.from(e.options).find(e=>"__custom__"===e.value);o?e.insertBefore(c,o):e.appendChild(c)}e.value=n,e.dataset.previousValue=n}(o)))})}function a(){n="connected"===n?"standalone":"connected";const o=document.getElementById("cliProcessMode");o&&(o.textContent="connected"===n?"π Connected Mode":"π Standalone Mode",o.style.color="connected"===n?"#10b981":"#6b7280"),"connected"===n?e():t()}async function i(){try{const e=await fetch("/api/settings/cli-models");if(e.ok){const o=await e.json(),t=(e,o)=>{const t=document.getElementById(e);if(!t)return;const n=o||"";if(n&&!Array.from(t.options).some(e=>e.value===n)){const e=document.createElement("option");e.value=n,e.textContent=`${n} (saved custom)`;const o=Array.from(t.options).find(e=>"__custom__"===e.value);o?t.insertBefore(e,o):t.appendChild(e)}t.value=n,t.dataset.previousValue=n};t("configChatModel",o.CREW_CHAT_MODEL),t("configRouterModel",o.CREW_ROUTER_MODEL),t("configReasoningModel",o.CREW_REASONING_MODEL),t("configL2AModel",o.CREW_L2A_MODEL),t("configL2BModel",o.CREW_L2B_MODEL),t("configExecutionModel",o.CREW_EXECUTION_MODEL),t("configQAModel",o.CREW_QA_MODEL),t("configMaxWorkers",o.CREW_MAX_PARALLEL_WORKERS||"6"),t("configExtraValidators",o.CREW_L2_EXTRA_VALIDATORS)}}catch(e){console.error("[CLI Process] Failed to load config:",e)}}async function d(){const e=function(){const e=e=>{var o;return(null==(o=document.getElementById(e))?void 0:o.value)||""};return{CREW_CHAT_MODEL:e("configChatModel"),CREW_ROUTER_MODEL:e("configRouterModel"),CREW_REASONING_MODEL:e("configReasoningModel"),CREW_L2A_MODEL:e("configL2AModel"),CREW_L2B_MODEL:e("configL2BModel"),CREW_EXECUTION_MODEL:e("configExecutionModel"),CREW_QA_MODEL:e("configQAModel"),CREW_MAX_PARALLEL_WORKERS:e("configMaxWorkers")||"6",CREW_L2_EXTRA_VALIDATORS:e("configExtraValidators")}}();try{const o=await fetch("/api/settings/cli-models",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!o.ok){const e=await o.json().catch(()=>({}));throw new Error(e.error||o.statusText)}alert("β
CLI configuration saved to crewswarm.json. Restart crew (Services β Start All) for changes to take effect.")}catch(o){alert("β Save failed: "+o.message)}}async function E(){const e={CREW_CHAT_MODEL:"grok-4-1-fast-non-reasoning",CREW_ROUTER_MODEL:"gpt-5.4",CREW_REASONING_MODEL:"gpt-5.4",CREW_L2A_MODEL:"gpt-5.4",CREW_L2B_MODEL:"gpt-5.4",CREW_EXECUTION_MODEL:"gemini-2.5-flash",CREW_QA_MODEL:"gpt-5.4",CREW_MAX_PARALLEL_WORKERS:"6",CREW_L2_EXTRA_VALIDATORS:""};document.getElementById("configChatModel").value=e.CREW_CHAT_MODEL,document.getElementById("configRouterModel").value=e.CREW_ROUTER_MODEL,document.getElementById("configReasoningModel").value=e.CREW_REASONING_MODEL,document.getElementById("configL2AModel").value=e.CREW_L2A_MODEL,document.getElementById("configL2BModel").value=e.CREW_L2B_MODEL,document.getElementById("configExecutionModel").value=e.CREW_EXECUTION_MODEL,document.getElementById("configQAModel").value=e.CREW_QA_MODEL,document.getElementById("configMaxWorkers").value=e.CREW_MAX_PARALLEL_WORKERS,document.getElementById("configExtraValidators").value=e.CREW_L2_EXTRA_VALIDATORS,c();try{(await fetch("/api/settings/cli-models",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok&&alert("β
Recommended stack applied. Restart crew for changes to take effect.")}catch(o){console.error("[CLI Process] Apply recommended failed:",o)}}async function l(){["configChatModel","configRouterModel","configReasoningModel","configL2AModel","configL2BModel","configExecutionModel","configQAModel","configExtraValidators"].forEach(e=>{const o=document.getElementById(e);o&&(o.value="")}),document.getElementById("configMaxWorkers").value="6";try{const e={CREW_CHAT_MODEL:"",CREW_ROUTER_MODEL:"",CREW_REASONING_MODEL:"",CREW_L2A_MODEL:"",CREW_L2B_MODEL:"",CREW_EXECUTION_MODEL:"",CREW_QA_MODEL:"",CREW_MAX_PARALLEL_WORKERS:"6",CREW_L2_EXTRA_VALIDATORS:""};await fetch("/api/settings/cli-models",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}catch(e){console.error("[CLI Process] Reset save failed:",e)}alert("β» Configuration reset")}window.initCLIProcess=async function(){var t,n,s,r,_;await i(),e(),null==(t=document.querySelector('[data-action="toggleCLIProcessMode"]'))||t.addEventListener("click",a),null==(n=document.querySelector('[data-action="saveCLIProcessConfig"]'))||n.addEventListener("click",d),null==(s=document.querySelector('[data-action="applyRecommendedCLIProcessConfig"]'))||s.addEventListener("click",E),null==(r=document.querySelector('[data-action="resetCLIProcessConfig"]'))||r.addEventListener("click",l),c(),null==(_=document.querySelector('[data-action="refreshCLIProcess"]'))||_.addEventListener("click",async()=>{await o(),await i()})};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t}from"./core-utils-CAVnDoe1.js";let e=null,n=[];function o(){const t=Date.now();return n=n.filter(e=>t-e.completedAt<3e5),n}function s(o="activeTasksPanel"){e=document.getElementById(o),e?(t.subscribe(o=>{const s=t.getActiveTasks(),r=new Set(s.map(t=>t.id));e._lastTaskIds&&e._lastTaskIds.forEach(t=>{if(!r.has(t)){n.find(e=>e.id===t)||n.push({id:t,agent:"Task",type:"completed",status:"completed",completedAt:Date.now(),startTime:Date.now()-3e4,duration:"30s"})}}),e._lastTaskIds=r,a(o)}),a(t.getActiveTasks())):console.warn("Active tasks panel container not found:",o)}function a(n){if(!e)return;const s=o(),r=[...n,...s];if(0===r.length)return void(e.style.display="none");e.style.display="block";const c=document.createElement("div");c.style.cssText="display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--surface-2);";const i=document.createElement("div");i.style.cssText="font-size:12px;font-weight:600;color:var(--text-1);";const d=n.length,l=s.length;i.textContent=`β‘ Tasks: ${d} active${l>0?`, ${l} completed`:""}`;const p=document.createElement("button");p.textContent="βΉ Stop All",p.style.cssText="font-size:11px;padding:3px 8px;border-radius:4px;border:1px solid var(--red-hi);background:transparent;color:var(--red-hi);cursor:pointer;",p.onclick=()=>{confirm("Stop all active tasks?")&&t.stopAll()},c.appendChild(i),d>0&&c.appendChild(p);const x=document.createElement("div");x.style.cssText="max-height:200px;overflow-y:auto;",r.forEach(e=>{const n="completed"===e.status||"failed"===e.status,o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--bg-card);"+(n?"opacity:0.6;":"");const s=document.createElement("span");s.style.cssText="font-size:14px;flex-shrink:0;","completed"===e.status?s.textContent="β
":"failed"===e.status?s.textContent="β":s.textContent="β‘";const a=document.createElement("span");a.style.cssText="font-size:10px;font-weight:600;padding:2px 6px;border-radius:12px;background:var(--purple);color:#fff;white-space:nowrap;",a.textContent=e.agent||e.type||"task";const r=document.createElement("div");r.style.cssText="flex:1;font-size:12px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;",r.textContent=e.description||(n?"Completed":"Working..."),r.title=e.description||"";const c=document.createElement("span");c.style.cssText="font-size:10px;color:var(--text-3);white-space:nowrap;";const i=e.duration||Math.floor((Date.now()-e.startTime)/1e3)+"s";if(c.textContent=i,o.appendChild(s),o.appendChild(a),o.appendChild(r),o.appendChild(c),!n){const n=document.createElement("button");n.textContent="βΉ",n.title="Stop this task",n.style.cssText="font-size:14px;padding:2px 6px;border-radius:4px;border:1px solid var(--border);background:var(--surface-2);color:var(--red-hi);cursor:pointer;",n.onclick=()=>{t.stopTask(e.id)},o.appendChild(n)}x.appendChild(o)}),e.replaceChildren(c,x),e._intervalSet||(e._intervalSet=!0,setInterval(()=>{const e=t.getActiveTasks();(e.length>0||o().length>0)&&a(e)},1e3))}export{s as i};
|
|
Binary file
|