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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestration Status Panel
|
|
3
|
+
* Live dashboard for crewswarm swarm coordination
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let orchestrationInterval = null;
|
|
7
|
+
|
|
8
|
+
export async function updateOrchestrationStatus() {
|
|
9
|
+
try {
|
|
10
|
+
// Get health check
|
|
11
|
+
const healthRes = await fetch('/api/health');
|
|
12
|
+
const health = healthRes.ok ? await healthRes.json() : { ok: false };
|
|
13
|
+
|
|
14
|
+
// Get agents status
|
|
15
|
+
const agentsRes = await fetch('/api/agents');
|
|
16
|
+
const agents = agentsRes.ok ? await agentsRes.json() : { count: 0 };
|
|
17
|
+
|
|
18
|
+
// Get project queue status
|
|
19
|
+
const queueRes = await fetch('/api/projects');
|
|
20
|
+
const projects = queueRes.ok ? await queueRes.json() : { projects: [] };
|
|
21
|
+
const allProjects = projects.projects || [];
|
|
22
|
+
const totalPending = allProjects.reduce((sum, p) => sum + (p.roadmap?.pending || 0), 0);
|
|
23
|
+
const totalRunning = allProjects.filter(p => p.running).length;
|
|
24
|
+
|
|
25
|
+
// Get configured models
|
|
26
|
+
const providersRes = await fetch('/api/providers');
|
|
27
|
+
const providers = providersRes.ok ? await providersRes.json() : { providers: [] };
|
|
28
|
+
const configuredProviders = (providers.providers || []).filter(p => p.configured);
|
|
29
|
+
const modelNames = configuredProviders.map(p => {
|
|
30
|
+
if (p.id === 'openai') return 'GPT';
|
|
31
|
+
if (p.id === 'anthropic') return 'Claude';
|
|
32
|
+
if (p.id === 'google') return 'Gemini';
|
|
33
|
+
if (p.id === 'groq') return 'Groq';
|
|
34
|
+
if (p.id === 'xai') return 'Grok';
|
|
35
|
+
if (p.id === 'ollama') return 'Local';
|
|
36
|
+
return p.label?.split(' ')[0];
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Update UI
|
|
40
|
+
const systemStatus = document.getElementById('orchSystemStatus');
|
|
41
|
+
const modelStack = document.getElementById('orchModelStack');
|
|
42
|
+
const swarmFill = document.getElementById('orchSwarmFill');
|
|
43
|
+
const swarmPercent = document.getElementById('orchSwarmPercent');
|
|
44
|
+
const activeAgents = document.getElementById('orchActiveAgents');
|
|
45
|
+
const taskQueue = document.getElementById('orchTaskQueue');
|
|
46
|
+
|
|
47
|
+
if (systemStatus) {
|
|
48
|
+
if (health.ok) {
|
|
49
|
+
systemStatus.textContent = '● ONLINE';
|
|
50
|
+
systemStatus.style.color = '#10b981'; // green
|
|
51
|
+
} else {
|
|
52
|
+
systemStatus.textContent = '● OFFLINE';
|
|
53
|
+
systemStatus.style.color = '#ef4444'; // red
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (modelStack) {
|
|
58
|
+
modelStack.textContent = modelNames.length > 0
|
|
59
|
+
? modelNames.slice(0, 3).join(' / ')
|
|
60
|
+
: 'Not configured';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const agentCount = agents.count || 0;
|
|
64
|
+
const maxAgents = 30;
|
|
65
|
+
const percent = Math.min(100, Math.floor((agentCount / maxAgents) * 100));
|
|
66
|
+
|
|
67
|
+
if (swarmFill) {
|
|
68
|
+
swarmFill.style.width = `${percent}%`;
|
|
69
|
+
}
|
|
70
|
+
if (swarmPercent) {
|
|
71
|
+
swarmPercent.textContent = `${percent}%`;
|
|
72
|
+
}
|
|
73
|
+
if (activeAgents) {
|
|
74
|
+
activeAgents.textContent = agentCount.toString();
|
|
75
|
+
}
|
|
76
|
+
if (taskQueue) {
|
|
77
|
+
const parts = [];
|
|
78
|
+
if (totalPending > 0) parts.push(`${totalPending} pending`);
|
|
79
|
+
if (totalRunning > 0) parts.push(`${totalRunning} running`);
|
|
80
|
+
taskQueue.textContent = parts.length > 0 ? parts.join(', ') : '0 pending';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.error('[OrchestrationStatus] Update failed:', err);
|
|
85
|
+
|
|
86
|
+
// Show error state
|
|
87
|
+
const systemStatus = document.getElementById('orchSystemStatus');
|
|
88
|
+
if (systemStatus) {
|
|
89
|
+
systemStatus.textContent = '● ERROR';
|
|
90
|
+
systemStatus.style.color = '#ef4444';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function startOrchestrationStatusUpdates() {
|
|
96
|
+
// Initial update
|
|
97
|
+
updateOrchestrationStatus();
|
|
98
|
+
|
|
99
|
+
// Update every 5 seconds
|
|
100
|
+
if (orchestrationInterval) {
|
|
101
|
+
clearInterval(orchestrationInterval);
|
|
102
|
+
}
|
|
103
|
+
orchestrationInterval = setInterval(updateOrchestrationStatus, 5000);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function stopOrchestrationStatusUpdates() {
|
|
107
|
+
if (orchestrationInterval) {
|
|
108
|
+
clearInterval(orchestrationInterval);
|
|
109
|
+
orchestrationInterval = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Auto-start when chat view is active
|
|
114
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
115
|
+
const chatView = document.getElementById('chatView');
|
|
116
|
+
if (chatView && chatView.classList.contains('active')) {
|
|
117
|
+
startOrchestrationStatusUpdates();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Restart when switching to chat view
|
|
122
|
+
const navChat = document.getElementById('navChat');
|
|
123
|
+
if (navChat) {
|
|
124
|
+
navChat.addEventListener('click', () => {
|
|
125
|
+
setTimeout(startOrchestrationStatusUpdates, 100);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup Wizard — first-run onboarding overlay for CrewSwarm dashboard.
|
|
3
|
+
* Shows when no API keys are configured (firstRun === true).
|
|
4
|
+
* Step 1: Welcome → Step 2: API Keys → Step 3: CLI Engines
|
|
5
|
+
* Vanilla JS, no frameworks. Matches the existing dark dashboard theme.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { getJSON, postJSON } from "./core/api.js";
|
|
9
|
+
|
|
10
|
+
// ── All supported providers (synced with models-tab.js BUILTIN_PROVIDERS) ────
|
|
11
|
+
const ALL_PROVIDERS = [
|
|
12
|
+
{ id: "anthropic", label: "Anthropic", icon: "\uD83D\uDFE3", placeholder: "sk-ant-...", url: "https://console.anthropic.com/" },
|
|
13
|
+
{ id: "openai", label: "OpenAI", icon: "\uD83D\uDFE2", placeholder: "sk-...", url: "https://platform.openai.com/api-keys" },
|
|
14
|
+
{ id: "google", label: "Google (Gemini)", icon: "\uD83D\uDD35", placeholder: "AIza...", url: "https://aistudio.google.com/apikey" },
|
|
15
|
+
{ id: "groq", label: "Groq", icon: "\u26A1", placeholder: "gsk_...", url: "https://console.groq.com/keys" },
|
|
16
|
+
{ id: "fireworks", label: "Fireworks AI", icon: "\uD83C\uDF86", placeholder: "fw_...", url: "https://fireworks.ai/" },
|
|
17
|
+
{ id: "openrouter", label: "OpenRouter", icon: "\uD83D\uDD00", placeholder: "sk-or-...", url: "https://openrouter.ai/keys" },
|
|
18
|
+
{ id: "xai", label: "xAI (Grok)", icon: "\uD835\uDD4F", placeholder: "xai-...", url: "https://console.x.ai/" },
|
|
19
|
+
{ id: "deepseek", label: "DeepSeek", icon: "\uD83C\uDF0A", placeholder: "sk-...", url: "https://platform.deepseek.com/" },
|
|
20
|
+
{ id: "mistral", label: "Mistral", icon: "\uD83C\uDF00", placeholder: "...", url: "https://console.mistral.ai/api-keys" },
|
|
21
|
+
{ id: "cerebras", label: "Cerebras", icon: "\uD83E\uDDE0", placeholder: "csk-...", url: "https://cloud.cerebras.ai/" },
|
|
22
|
+
{ id: "nvidia", label: "NVIDIA NIM", icon: "\uD83C\uDFAE", placeholder: "nvapi-...", url: "https://build.nvidia.com/" },
|
|
23
|
+
{ id: "perplexity", label: "Perplexity", icon: "\uD83D\uDD0D", placeholder: "pplx-...", url: "https://www.perplexity.ai/settings/api" },
|
|
24
|
+
{ id: "ollama", label: "Ollama (local)", icon: "\uD83C\uDFE0", placeholder: "no key needed", url: "https://ollama.com/download" },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// ── CLI engines we can detect ────────────────────────────────────────────────
|
|
28
|
+
const CLI_ENGINES = [
|
|
29
|
+
{ id: "claude-code", cmd: "claude", label: "Claude Code", desc: "Anthropic's CLI agent. Best for complex reasoning and multi-file refactors.", installUrl: "https://docs.anthropic.com/en/docs/claude-code/overview", authCmd: "claude auth", keyProvider: "anthropic" },
|
|
30
|
+
{ id: "codex", cmd: "codex", label: "Codex CLI", desc: "OpenAI's CLI agent. Sandboxed execution with full file write access.", installUrl: "https://github.com/openai/codex", authCmd: "codex auth", keyProvider: "openai" },
|
|
31
|
+
{ id: "crew-cli", cmd: "crew", label: "crew-cli", desc: "CrewSwarm's own 3-tier pipeline. Supports Anthropic, OpenAI, Gemini, Groq, DeepSeek, and more.", installUrl: null, authCmd: null, keyProvider: null },
|
|
32
|
+
{ id: "opencode", cmd: "opencode", label: "OpenCode", desc: "Multi-provider CLI agent. Supports OpenAI, Anthropic, Google, and more.", installUrl: "https://github.com/opencode-ai/opencode", authCmd: null, keyProvider: null },
|
|
33
|
+
{ id: "gemini-cli", cmd: "gemini", label: "Gemini CLI", desc: "Google's CLI agent. Fast inference with Gemini models.", installUrl: "https://github.com/google-gemini/gemini-cli", authCmd: "gemini auth", keyProvider: "google" },
|
|
34
|
+
{ id: "cursor", cmd: "cursor", label: "Cursor CLI", desc: "Cursor's agent mode via CLI. Requires Cursor IDE installed.", installUrl: "https://www.cursor.com/", authCmd: null, keyProvider: null },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
let _currentStep = 1;
|
|
38
|
+
let _overlayEl = null;
|
|
39
|
+
let _providerKeys = {}; // only keys the user actually typed
|
|
40
|
+
let _configuredProviders = []; // already-configured provider IDs from backend
|
|
41
|
+
let _detectedEngines = {}; // { engineId: true/false }
|
|
42
|
+
|
|
43
|
+
// ── Public API ──────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check first-run status and show wizard if needed.
|
|
47
|
+
* Returns true if wizard was shown, false if skipped.
|
|
48
|
+
*/
|
|
49
|
+
export async function checkFirstRun() {
|
|
50
|
+
try {
|
|
51
|
+
const data = await getJSON("/api/first-run-status");
|
|
52
|
+
const forceWizard = new URLSearchParams(window.location.search).has("wizard");
|
|
53
|
+
if (!data.firstRun && !forceWizard) return false;
|
|
54
|
+
_configuredProviders = data.configuredProviders || [];
|
|
55
|
+
_showWizard();
|
|
56
|
+
return true;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.warn("[setup-wizard] Could not check first-run status:", e);
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── Wizard rendering ────────────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
function _showWizard() {
|
|
66
|
+
_currentStep = 1;
|
|
67
|
+
_providerKeys = {};
|
|
68
|
+
|
|
69
|
+
_overlayEl = document.createElement("div");
|
|
70
|
+
_overlayEl.id = "setupWizardOverlay";
|
|
71
|
+
_overlayEl.className = "setup-wizard-overlay";
|
|
72
|
+
_overlayEl.setAttribute("role", "dialog");
|
|
73
|
+
_overlayEl.setAttribute("aria-modal", "true");
|
|
74
|
+
_overlayEl.setAttribute("aria-label", "CrewSwarm setup wizard");
|
|
75
|
+
|
|
76
|
+
_renderStep();
|
|
77
|
+
document.body.appendChild(_overlayEl);
|
|
78
|
+
|
|
79
|
+
// Force reflow then animate in
|
|
80
|
+
_overlayEl.offsetHeight;
|
|
81
|
+
_overlayEl.classList.add("visible");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function _renderStep() {
|
|
85
|
+
if (!_overlayEl) return;
|
|
86
|
+
|
|
87
|
+
const card = _buildStepContent();
|
|
88
|
+
_overlayEl.innerHTML = "";
|
|
89
|
+
|
|
90
|
+
const wrapper = document.createElement("div");
|
|
91
|
+
wrapper.className = "setup-wizard-card";
|
|
92
|
+
wrapper.appendChild(_buildStepIndicator());
|
|
93
|
+
wrapper.appendChild(card);
|
|
94
|
+
_overlayEl.appendChild(wrapper);
|
|
95
|
+
|
|
96
|
+
requestAnimationFrame(() => {
|
|
97
|
+
wrapper.classList.add("visible");
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function _buildStepIndicator() {
|
|
102
|
+
const labels = ["Welcome", "API Keys", "Engines"];
|
|
103
|
+
const indicator = document.createElement("div");
|
|
104
|
+
indicator.className = "setup-wizard-steps";
|
|
105
|
+
indicator.setAttribute("aria-label", `Step ${_currentStep} of 3`);
|
|
106
|
+
|
|
107
|
+
for (let i = 1; i <= 3; i++) {
|
|
108
|
+
const dot = document.createElement("button");
|
|
109
|
+
dot.className = "setup-wizard-step-dot";
|
|
110
|
+
dot.setAttribute("aria-label", `Step ${i}`);
|
|
111
|
+
dot.tabIndex = -1;
|
|
112
|
+
if (i === _currentStep) dot.classList.add("active");
|
|
113
|
+
if (i < _currentStep) dot.classList.add("completed");
|
|
114
|
+
|
|
115
|
+
const label = document.createElement("span");
|
|
116
|
+
label.className = "setup-wizard-step-label";
|
|
117
|
+
label.textContent = labels[i - 1];
|
|
118
|
+
|
|
119
|
+
const step = document.createElement("div");
|
|
120
|
+
step.className = "setup-wizard-step";
|
|
121
|
+
step.appendChild(dot);
|
|
122
|
+
step.appendChild(label);
|
|
123
|
+
indicator.appendChild(step);
|
|
124
|
+
|
|
125
|
+
if (i < 3) {
|
|
126
|
+
const line = document.createElement("div");
|
|
127
|
+
line.className = "setup-wizard-step-line";
|
|
128
|
+
if (i < _currentStep) line.classList.add("completed");
|
|
129
|
+
indicator.appendChild(line);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return indicator;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function _buildStepContent() {
|
|
137
|
+
switch (_currentStep) {
|
|
138
|
+
case 1: return _buildWelcomeStep();
|
|
139
|
+
case 2: return _buildProvidersStep();
|
|
140
|
+
case 3: return _buildEnginesStep();
|
|
141
|
+
default: return _buildWelcomeStep();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ── Step 1: Welcome ─────────────────────────────────────────────────────────
|
|
146
|
+
|
|
147
|
+
function _buildWelcomeStep() {
|
|
148
|
+
const frag = document.createElement("div");
|
|
149
|
+
frag.className = "setup-wizard-content";
|
|
150
|
+
|
|
151
|
+
frag.innerHTML = `
|
|
152
|
+
<div class="setup-wizard-hero">
|
|
153
|
+
<div class="setup-wizard-logo-ring">
|
|
154
|
+
<img src="/favicon.png" alt="CrewSwarm" class="setup-wizard-logo" />
|
|
155
|
+
</div>
|
|
156
|
+
<h1 class="setup-wizard-title">Welcome to CrewSwarm</h1>
|
|
157
|
+
<p class="setup-wizard-subtitle">
|
|
158
|
+
Multi-agent orchestration for AI coding tools.<br>
|
|
159
|
+
Let's get you set up in 2 minutes.
|
|
160
|
+
</p>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="setup-wizard-checklist">
|
|
163
|
+
<div class="setup-wizard-check-item">
|
|
164
|
+
<span class="setup-wizard-check-icon done">✓</span>
|
|
165
|
+
<span>Dashboard installed</span>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="setup-wizard-check-item">
|
|
168
|
+
<span class="setup-wizard-check-icon pending">•</span>
|
|
169
|
+
<span>Add API provider keys</span>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="setup-wizard-check-item">
|
|
172
|
+
<span class="setup-wizard-check-icon pending">•</span>
|
|
173
|
+
<span>Detect & configure CLI engines</span>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
const actions = document.createElement("div");
|
|
179
|
+
actions.className = "setup-wizard-actions";
|
|
180
|
+
|
|
181
|
+
const nextBtn = document.createElement("button");
|
|
182
|
+
nextBtn.className = "setup-wizard-btn-primary";
|
|
183
|
+
nextBtn.textContent = "Get Started";
|
|
184
|
+
nextBtn.addEventListener("click", () => {
|
|
185
|
+
_currentStep = 2;
|
|
186
|
+
_renderStep();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const skipBtn = document.createElement("button");
|
|
190
|
+
skipBtn.className = "setup-wizard-btn-ghost";
|
|
191
|
+
skipBtn.textContent = "Skip setup";
|
|
192
|
+
skipBtn.addEventListener("click", _dismiss);
|
|
193
|
+
|
|
194
|
+
actions.appendChild(nextBtn);
|
|
195
|
+
actions.appendChild(skipBtn);
|
|
196
|
+
frag.appendChild(actions);
|
|
197
|
+
|
|
198
|
+
return frag;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ── Step 2: API Keys ────────────────────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
function _buildProvidersStep() {
|
|
204
|
+
const frag = document.createElement("div");
|
|
205
|
+
frag.className = "setup-wizard-content";
|
|
206
|
+
|
|
207
|
+
const header = document.createElement("div");
|
|
208
|
+
header.className = "setup-wizard-section-header";
|
|
209
|
+
header.innerHTML = `
|
|
210
|
+
<h2 class="setup-wizard-section-title">API Keys</h2>
|
|
211
|
+
<p class="setup-wizard-section-desc">
|
|
212
|
+
Add keys for the providers you want to use. Already-configured keys are shown with a checkmark.
|
|
213
|
+
Only new keys you enter will be saved — existing keys won't be touched.
|
|
214
|
+
</p>
|
|
215
|
+
`;
|
|
216
|
+
frag.appendChild(header);
|
|
217
|
+
|
|
218
|
+
const list = document.createElement("div");
|
|
219
|
+
list.className = "setup-wizard-provider-list";
|
|
220
|
+
|
|
221
|
+
for (const prov of ALL_PROVIDERS) {
|
|
222
|
+
const alreadyConfigured = _configuredProviders.includes(prov.id);
|
|
223
|
+
|
|
224
|
+
const row = document.createElement("div");
|
|
225
|
+
row.className = "setup-wizard-provider-row";
|
|
226
|
+
if (alreadyConfigured) row.classList.add("already-configured");
|
|
227
|
+
|
|
228
|
+
const labelWrap = document.createElement("div");
|
|
229
|
+
labelWrap.className = "setup-wizard-provider-label";
|
|
230
|
+
|
|
231
|
+
const provIcon = document.createElement("span");
|
|
232
|
+
provIcon.className = "setup-wizard-provider-icon";
|
|
233
|
+
provIcon.textContent = prov.icon || "";
|
|
234
|
+
|
|
235
|
+
const statusIcon = document.createElement("span");
|
|
236
|
+
statusIcon.className = "setup-wizard-provider-status";
|
|
237
|
+
statusIcon.textContent = alreadyConfigured ? "\u2713" : "";
|
|
238
|
+
statusIcon.title = alreadyConfigured ? "Already configured" : "Not configured";
|
|
239
|
+
|
|
240
|
+
const name = document.createElement("span");
|
|
241
|
+
name.className = "setup-wizard-provider-name";
|
|
242
|
+
name.textContent = prov.label;
|
|
243
|
+
|
|
244
|
+
const link = document.createElement("a");
|
|
245
|
+
link.href = prov.url;
|
|
246
|
+
link.target = "_blank";
|
|
247
|
+
link.rel = "noopener";
|
|
248
|
+
link.className = "setup-wizard-provider-link";
|
|
249
|
+
link.textContent = "Get key";
|
|
250
|
+
link.setAttribute("aria-label", `Get API key for ${prov.label}`);
|
|
251
|
+
|
|
252
|
+
labelWrap.appendChild(provIcon);
|
|
253
|
+
labelWrap.appendChild(name);
|
|
254
|
+
labelWrap.appendChild(statusIcon);
|
|
255
|
+
labelWrap.appendChild(link);
|
|
256
|
+
|
|
257
|
+
const inputWrap = document.createElement("div");
|
|
258
|
+
inputWrap.className = "setup-wizard-provider-input-wrap";
|
|
259
|
+
|
|
260
|
+
const input = document.createElement("input");
|
|
261
|
+
input.type = "password";
|
|
262
|
+
input.className = "setup-wizard-provider-input";
|
|
263
|
+
input.placeholder = alreadyConfigured ? "configured \u2713" : prov.placeholder;
|
|
264
|
+
input.autocomplete = "off";
|
|
265
|
+
input.spellcheck = false;
|
|
266
|
+
input.dataset.providerId = prov.id;
|
|
267
|
+
input.setAttribute("aria-label", `API key for ${prov.label}`);
|
|
268
|
+
|
|
269
|
+
if (_providerKeys[prov.id]) {
|
|
270
|
+
input.value = _providerKeys[prov.id];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
input.addEventListener("input", () => {
|
|
274
|
+
const val = input.value.trim();
|
|
275
|
+
if (val) {
|
|
276
|
+
_providerKeys[prov.id] = val;
|
|
277
|
+
row.classList.add("has-key");
|
|
278
|
+
} else {
|
|
279
|
+
delete _providerKeys[prov.id];
|
|
280
|
+
row.classList.remove("has-key");
|
|
281
|
+
}
|
|
282
|
+
_updateSaveBtn();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const toggleVis = document.createElement("button");
|
|
286
|
+
toggleVis.type = "button";
|
|
287
|
+
toggleVis.className = "setup-wizard-toggle-vis";
|
|
288
|
+
toggleVis.textContent = "\uD83D\uDC41";
|
|
289
|
+
toggleVis.setAttribute("aria-label", "Toggle key visibility");
|
|
290
|
+
toggleVis.addEventListener("click", () => {
|
|
291
|
+
input.type = input.type === "password" ? "text" : "password";
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
inputWrap.appendChild(input);
|
|
295
|
+
inputWrap.appendChild(toggleVis);
|
|
296
|
+
|
|
297
|
+
row.appendChild(labelWrap);
|
|
298
|
+
row.appendChild(inputWrap);
|
|
299
|
+
|
|
300
|
+
if (_providerKeys[prov.id]) {
|
|
301
|
+
row.classList.add("has-key");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
list.appendChild(row);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
frag.appendChild(list);
|
|
308
|
+
|
|
309
|
+
const errorEl = document.createElement("div");
|
|
310
|
+
errorEl.className = "setup-wizard-error hidden";
|
|
311
|
+
errorEl.id = "wizardProviderError";
|
|
312
|
+
frag.appendChild(errorEl);
|
|
313
|
+
|
|
314
|
+
const actions = document.createElement("div");
|
|
315
|
+
actions.className = "setup-wizard-actions";
|
|
316
|
+
|
|
317
|
+
const backBtn = document.createElement("button");
|
|
318
|
+
backBtn.className = "setup-wizard-btn-ghost";
|
|
319
|
+
backBtn.textContent = "Back";
|
|
320
|
+
backBtn.addEventListener("click", () => {
|
|
321
|
+
_currentStep = 1;
|
|
322
|
+
_renderStep();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const saveBtn = document.createElement("button");
|
|
326
|
+
saveBtn.className = "setup-wizard-btn-primary";
|
|
327
|
+
saveBtn.id = "wizardSaveBtn";
|
|
328
|
+
// Allow continuing even without new keys (they may all be pre-configured)
|
|
329
|
+
const hasNewKeys = Object.keys(_providerKeys).length > 0;
|
|
330
|
+
const hasExistingKeys = _configuredProviders.length > 0;
|
|
331
|
+
saveBtn.textContent = hasNewKeys ? "Save & Continue" : "Continue";
|
|
332
|
+
saveBtn.disabled = !hasNewKeys && !hasExistingKeys;
|
|
333
|
+
saveBtn.addEventListener("click", _saveProviders);
|
|
334
|
+
|
|
335
|
+
actions.appendChild(backBtn);
|
|
336
|
+
actions.appendChild(saveBtn);
|
|
337
|
+
frag.appendChild(actions);
|
|
338
|
+
|
|
339
|
+
return frag;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function _updateSaveBtn() {
|
|
343
|
+
const btn = document.getElementById("wizardSaveBtn");
|
|
344
|
+
if (!btn) return;
|
|
345
|
+
const hasNewKeys = Object.keys(_providerKeys).length > 0;
|
|
346
|
+
const hasExistingKeys = _configuredProviders.length > 0;
|
|
347
|
+
btn.textContent = hasNewKeys ? "Save & Continue" : "Continue";
|
|
348
|
+
btn.disabled = !hasNewKeys && !hasExistingKeys;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async function _saveProviders() {
|
|
352
|
+
const btn = document.getElementById("wizardSaveBtn");
|
|
353
|
+
const errorEl = document.getElementById("wizardProviderError");
|
|
354
|
+
|
|
355
|
+
const newKeys = Object.entries(_providerKeys).filter(([, v]) => v && v.length > 0);
|
|
356
|
+
|
|
357
|
+
if (newKeys.length > 0) {
|
|
358
|
+
if (btn) {
|
|
359
|
+
btn.disabled = true;
|
|
360
|
+
btn.textContent = "Saving...";
|
|
361
|
+
}
|
|
362
|
+
if (errorEl) errorEl.classList.add("hidden");
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
for (const [providerId, apiKey] of newKeys) {
|
|
366
|
+
await postJSON("/api/providers/builtin/save", { providerId, apiKey });
|
|
367
|
+
}
|
|
368
|
+
} catch (e) {
|
|
369
|
+
if (errorEl) {
|
|
370
|
+
errorEl.textContent = "Failed to save: " + (e.message || "Unknown error");
|
|
371
|
+
errorEl.classList.remove("hidden");
|
|
372
|
+
}
|
|
373
|
+
if (btn) {
|
|
374
|
+
btn.disabled = false;
|
|
375
|
+
btn.textContent = "Save & Continue";
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Detect engines before showing step 3
|
|
382
|
+
await _detectEngines();
|
|
383
|
+
_currentStep = 3;
|
|
384
|
+
_renderStep();
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// ── Step 3: CLI Engines ─────────────────────────────────────────────────────
|
|
388
|
+
|
|
389
|
+
async function _detectEngines() {
|
|
390
|
+
try {
|
|
391
|
+
const data = await getJSON("/api/first-run-engines");
|
|
392
|
+
_detectedEngines = data.engines || {};
|
|
393
|
+
} catch {
|
|
394
|
+
// If endpoint doesn't exist yet, fall back to empty
|
|
395
|
+
_detectedEngines = {};
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function _buildEnginesStep() {
|
|
400
|
+
const frag = document.createElement("div");
|
|
401
|
+
frag.className = "setup-wizard-content";
|
|
402
|
+
|
|
403
|
+
const header = document.createElement("div");
|
|
404
|
+
header.className = "setup-wizard-section-header";
|
|
405
|
+
header.innerHTML = `
|
|
406
|
+
<h2 class="setup-wizard-section-title">CLI Engines</h2>
|
|
407
|
+
<p class="setup-wizard-section-desc">
|
|
408
|
+
CrewSwarm dispatches tasks to these CLI coding agents.
|
|
409
|
+
You need at least one installed. Use the API keys from Step 2 to authenticate.
|
|
410
|
+
</p>
|
|
411
|
+
`;
|
|
412
|
+
frag.appendChild(header);
|
|
413
|
+
|
|
414
|
+
const grid = document.createElement("div");
|
|
415
|
+
grid.className = "setup-wizard-engine-grid";
|
|
416
|
+
|
|
417
|
+
const detectedCount = Object.values(_detectedEngines).filter(Boolean).length;
|
|
418
|
+
|
|
419
|
+
for (const engine of CLI_ENGINES) {
|
|
420
|
+
const detected = _detectedEngines[engine.id] === true;
|
|
421
|
+
// crew-cli is always available (it's part of this repo)
|
|
422
|
+
const available = engine.id === "crew-cli" || detected;
|
|
423
|
+
|
|
424
|
+
const card = document.createElement("div");
|
|
425
|
+
card.className = "setup-wizard-engine-card";
|
|
426
|
+
if (available) card.classList.add("available");
|
|
427
|
+
|
|
428
|
+
// Status badge
|
|
429
|
+
const badge = document.createElement("div");
|
|
430
|
+
badge.className = "setup-wizard-engine-badge";
|
|
431
|
+
if (available) {
|
|
432
|
+
badge.textContent = "\u2713 Installed";
|
|
433
|
+
badge.classList.add("installed");
|
|
434
|
+
} else {
|
|
435
|
+
badge.textContent = "Not found";
|
|
436
|
+
badge.classList.add("missing");
|
|
437
|
+
}
|
|
438
|
+
card.appendChild(badge);
|
|
439
|
+
|
|
440
|
+
// Engine name + command
|
|
441
|
+
const title = document.createElement("div");
|
|
442
|
+
title.className = "setup-wizard-engine-title";
|
|
443
|
+
title.textContent = engine.label;
|
|
444
|
+
card.appendChild(title);
|
|
445
|
+
|
|
446
|
+
const cmd = document.createElement("code");
|
|
447
|
+
cmd.className = "setup-wizard-engine-cmd";
|
|
448
|
+
cmd.textContent = engine.cmd;
|
|
449
|
+
card.appendChild(cmd);
|
|
450
|
+
|
|
451
|
+
// Description
|
|
452
|
+
const desc = document.createElement("p");
|
|
453
|
+
desc.className = "setup-wizard-engine-desc";
|
|
454
|
+
desc.textContent = engine.desc;
|
|
455
|
+
card.appendChild(desc);
|
|
456
|
+
|
|
457
|
+
// Action area
|
|
458
|
+
const actionArea = document.createElement("div");
|
|
459
|
+
actionArea.className = "setup-wizard-engine-action";
|
|
460
|
+
|
|
461
|
+
if (available && engine.authCmd) {
|
|
462
|
+
const authLabel = document.createElement("span");
|
|
463
|
+
authLabel.className = "setup-wizard-engine-auth-label";
|
|
464
|
+
authLabel.textContent = "Auth:";
|
|
465
|
+
const authCode = document.createElement("code");
|
|
466
|
+
authCode.className = "setup-wizard-engine-auth-cmd";
|
|
467
|
+
authCode.textContent = engine.authCmd;
|
|
468
|
+
actionArea.appendChild(authLabel);
|
|
469
|
+
actionArea.appendChild(authCode);
|
|
470
|
+
} else if (available && engine.keyProvider) {
|
|
471
|
+
const keyNote = document.createElement("span");
|
|
472
|
+
keyNote.className = "setup-wizard-engine-key-note";
|
|
473
|
+
const provLabel = ALL_PROVIDERS.find(p => p.id === engine.keyProvider)?.label || engine.keyProvider;
|
|
474
|
+
const hasKey = _configuredProviders.includes(engine.keyProvider);
|
|
475
|
+
keyNote.textContent = hasKey ? `Uses ${provLabel} key \u2713` : `Needs ${provLabel} key`;
|
|
476
|
+
keyNote.classList.add(hasKey ? "key-ok" : "key-missing");
|
|
477
|
+
actionArea.appendChild(keyNote);
|
|
478
|
+
} else if (!available && engine.installUrl) {
|
|
479
|
+
const installLink = document.createElement("a");
|
|
480
|
+
installLink.href = engine.installUrl;
|
|
481
|
+
installLink.target = "_blank";
|
|
482
|
+
installLink.rel = "noopener";
|
|
483
|
+
installLink.className = "setup-wizard-engine-install-btn";
|
|
484
|
+
installLink.textContent = "Install \u2192";
|
|
485
|
+
actionArea.appendChild(installLink);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
card.appendChild(actionArea);
|
|
489
|
+
grid.appendChild(card);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
frag.appendChild(grid);
|
|
493
|
+
|
|
494
|
+
if (detectedCount === 0 && Object.keys(_detectedEngines).length > 0) {
|
|
495
|
+
const hint = document.createElement("p");
|
|
496
|
+
hint.className = "setup-wizard-engine-hint";
|
|
497
|
+
hint.innerHTML = "No external CLI engines detected. <strong>crew-cli</strong> is built in and always available.";
|
|
498
|
+
frag.appendChild(hint);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const actions = document.createElement("div");
|
|
502
|
+
actions.className = "setup-wizard-actions";
|
|
503
|
+
|
|
504
|
+
const backBtn = document.createElement("button");
|
|
505
|
+
backBtn.className = "setup-wizard-btn-ghost";
|
|
506
|
+
backBtn.textContent = "Back";
|
|
507
|
+
backBtn.addEventListener("click", () => {
|
|
508
|
+
_currentStep = 2;
|
|
509
|
+
_renderStep();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const startBtn = document.createElement("button");
|
|
513
|
+
startBtn.className = "setup-wizard-btn-primary setup-wizard-btn-start";
|
|
514
|
+
startBtn.textContent = "Launch Dashboard";
|
|
515
|
+
startBtn.addEventListener("click", _finishSetup);
|
|
516
|
+
|
|
517
|
+
actions.appendChild(backBtn);
|
|
518
|
+
actions.appendChild(startBtn);
|
|
519
|
+
frag.appendChild(actions);
|
|
520
|
+
|
|
521
|
+
return frag;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// ── Finish / dismiss ────────────────────────────────────────────────────────
|
|
525
|
+
|
|
526
|
+
async function _finishSetup() {
|
|
527
|
+
const btn = _overlayEl?.querySelector(".setup-wizard-btn-start");
|
|
528
|
+
if (btn) {
|
|
529
|
+
btn.disabled = true;
|
|
530
|
+
btn.textContent = "Loading...";
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
_dismiss();
|
|
534
|
+
window.location.href = window.location.pathname; // strip ?wizard param
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function _dismiss() {
|
|
538
|
+
if (!_overlayEl) return;
|
|
539
|
+
_overlayEl.classList.remove("visible");
|
|
540
|
+
_overlayEl.classList.add("dismissing");
|
|
541
|
+
_overlayEl.addEventListener(
|
|
542
|
+
"transitionend",
|
|
543
|
+
() => {
|
|
544
|
+
_overlayEl.remove();
|
|
545
|
+
_overlayEl = null;
|
|
546
|
+
},
|
|
547
|
+
{ once: true },
|
|
548
|
+
);
|
|
549
|
+
setTimeout(() => {
|
|
550
|
+
if (_overlayEl) {
|
|
551
|
+
_overlayEl.remove();
|
|
552
|
+
_overlayEl = null;
|
|
553
|
+
}
|
|
554
|
+
}, 400);
|
|
555
|
+
}
|
|
Binary file
|