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,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active Tasks Panel - Shows running tasks with individual controls
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { taskManager } from '../core/task-manager.js';
|
|
6
|
+
|
|
7
|
+
let _container = null;
|
|
8
|
+
let _completedTasks = []; // Track recently completed tasks
|
|
9
|
+
const COMPLETED_TASK_RETENTION_MS = 5 * 60 * 1000; // Keep for 5 minutes
|
|
10
|
+
|
|
11
|
+
function getRecentCompletedTasks() {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
// Filter out tasks older than 5 minutes
|
|
14
|
+
_completedTasks = _completedTasks.filter(t => now - t.completedAt < COMPLETED_TASK_RETENTION_MS);
|
|
15
|
+
return _completedTasks;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function initActiveTasksPanel(containerId = 'activeTasksPanel') {
|
|
19
|
+
_container = document.getElementById(containerId);
|
|
20
|
+
if (!_container) {
|
|
21
|
+
console.warn('Active tasks panel container not found:', containerId);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Subscribe to task changes
|
|
26
|
+
taskManager.subscribe((tasks) => {
|
|
27
|
+
// Track completed tasks before they're removed
|
|
28
|
+
const activeTasks = taskManager.getActiveTasks();
|
|
29
|
+
const taskIds = new Set(activeTasks.map(t => t.id));
|
|
30
|
+
|
|
31
|
+
// Find tasks that just completed (were in list before, not anymore)
|
|
32
|
+
if (_container._lastTaskIds) {
|
|
33
|
+
_container._lastTaskIds.forEach(oldId => {
|
|
34
|
+
if (!taskIds.has(oldId)) {
|
|
35
|
+
// Task completed or failed - add to completed list
|
|
36
|
+
const existingCompleted = _completedTasks.find(t => t.id === oldId);
|
|
37
|
+
if (!existingCompleted) {
|
|
38
|
+
_completedTasks.push({
|
|
39
|
+
id: oldId,
|
|
40
|
+
agent: 'Task',
|
|
41
|
+
type: 'completed',
|
|
42
|
+
status: 'completed',
|
|
43
|
+
completedAt: Date.now(),
|
|
44
|
+
startTime: Date.now() - 30000, // Estimate it took 30s
|
|
45
|
+
duration: '30s'
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_container._lastTaskIds = taskIds;
|
|
53
|
+
renderTasksPanel(tasks);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Initial render
|
|
57
|
+
renderTasksPanel(taskManager.getActiveTasks());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function renderTasksPanel(tasks) {
|
|
61
|
+
if (!_container) return;
|
|
62
|
+
|
|
63
|
+
// Get recent completed tasks
|
|
64
|
+
const recentCompletions = getRecentCompletedTasks();
|
|
65
|
+
const allTasks = [...tasks, ...recentCompletions];
|
|
66
|
+
|
|
67
|
+
if (allTasks.length === 0) {
|
|
68
|
+
_container.style.display = 'none';
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_container.style.display = 'block';
|
|
73
|
+
|
|
74
|
+
const header = document.createElement('div');
|
|
75
|
+
header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--surface-2);';
|
|
76
|
+
|
|
77
|
+
const title = document.createElement('div');
|
|
78
|
+
title.style.cssText = 'font-size:12px;font-weight:600;color:var(--text-1);';
|
|
79
|
+
const activeCount = tasks.length;
|
|
80
|
+
const completedCount = recentCompletions.length;
|
|
81
|
+
title.textContent = `⚡ Tasks: ${activeCount} active${completedCount > 0 ? `, ${completedCount} completed` : ''}`;
|
|
82
|
+
|
|
83
|
+
const stopAllBtn = document.createElement('button');
|
|
84
|
+
stopAllBtn.textContent = '⏹ Stop All';
|
|
85
|
+
stopAllBtn.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;';
|
|
86
|
+
stopAllBtn.onclick = () => {
|
|
87
|
+
if (confirm('Stop all active tasks?')) {
|
|
88
|
+
taskManager.stopAll();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
header.appendChild(title);
|
|
93
|
+
if (activeCount > 0) header.appendChild(stopAllBtn);
|
|
94
|
+
|
|
95
|
+
const tasksList = document.createElement('div');
|
|
96
|
+
tasksList.style.cssText = 'max-height:200px;overflow-y:auto;';
|
|
97
|
+
|
|
98
|
+
allTasks.forEach((task) => {
|
|
99
|
+
const isCompleted = task.status === 'completed' || task.status === 'failed';
|
|
100
|
+
const taskRow = document.createElement('div');
|
|
101
|
+
taskRow.style.cssText = `display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--bg-card);${isCompleted ? 'opacity:0.6;' : ''}`;
|
|
102
|
+
|
|
103
|
+
// Status icon
|
|
104
|
+
const statusIcon = document.createElement('span');
|
|
105
|
+
statusIcon.style.cssText = 'font-size:14px;flex-shrink:0;';
|
|
106
|
+
if (task.status === 'completed') {
|
|
107
|
+
statusIcon.textContent = '✅';
|
|
108
|
+
} else if (task.status === 'failed') {
|
|
109
|
+
statusIcon.textContent = '❌';
|
|
110
|
+
} else {
|
|
111
|
+
statusIcon.textContent = '⚡';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Agent badge
|
|
115
|
+
const agentBadge = document.createElement('span');
|
|
116
|
+
agentBadge.style.cssText = 'font-size:10px;font-weight:600;padding:2px 6px;border-radius:12px;background:var(--purple);color:#fff;white-space:nowrap;';
|
|
117
|
+
agentBadge.textContent = task.agent || task.type || 'task';
|
|
118
|
+
|
|
119
|
+
// Task description
|
|
120
|
+
const desc = document.createElement('div');
|
|
121
|
+
desc.style.cssText = 'flex:1;font-size:12px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
122
|
+
desc.textContent = task.description || (isCompleted ? 'Completed' : 'Working...');
|
|
123
|
+
desc.title = task.description || '';
|
|
124
|
+
|
|
125
|
+
// Duration
|
|
126
|
+
const duration = document.createElement('span');
|
|
127
|
+
duration.style.cssText = 'font-size:10px;color:var(--text-3);white-space:nowrap;';
|
|
128
|
+
const elapsed = task.duration || (Math.floor((Date.now() - task.startTime) / 1000) + 's');
|
|
129
|
+
duration.textContent = elapsed;
|
|
130
|
+
|
|
131
|
+
taskRow.appendChild(statusIcon);
|
|
132
|
+
taskRow.appendChild(agentBadge);
|
|
133
|
+
taskRow.appendChild(desc);
|
|
134
|
+
taskRow.appendChild(duration);
|
|
135
|
+
|
|
136
|
+
// Stop button only for active tasks
|
|
137
|
+
if (!isCompleted) {
|
|
138
|
+
const stopBtn = document.createElement('button');
|
|
139
|
+
stopBtn.textContent = '⏹';
|
|
140
|
+
stopBtn.title = 'Stop this task';
|
|
141
|
+
stopBtn.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;';
|
|
142
|
+
stopBtn.onclick = () => {
|
|
143
|
+
taskManager.stopTask(task.id);
|
|
144
|
+
};
|
|
145
|
+
taskRow.appendChild(stopBtn);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
tasksList.appendChild(taskRow);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
_container.replaceChildren(header, tasksList);
|
|
152
|
+
|
|
153
|
+
// Update durations every second
|
|
154
|
+
if (!_container._intervalSet) {
|
|
155
|
+
_container._intervalSet = true;
|
|
156
|
+
setInterval(() => {
|
|
157
|
+
const activeTasks = taskManager.getActiveTasks();
|
|
158
|
+
if (activeTasks.length > 0 || getRecentCompletedTasks().length > 0) {
|
|
159
|
+
renderTasksPanel(activeTasks);
|
|
160
|
+
}
|
|
161
|
+
}, 1000);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function showActiveTasksPanel() {
|
|
166
|
+
if (_container) {
|
|
167
|
+
_container.style.display = 'block';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function hideActiveTasksPanel() {
|
|
172
|
+
if (_container) {
|
|
173
|
+
_container.style.display = 'none';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Simple fetch wrapper - no cache for dev tools
|
|
2
|
+
export async function getJSON(p, { ttl = 0, bust = false } = {}) {
|
|
3
|
+
const r = await fetch(p);
|
|
4
|
+
if (!r.ok) throw new Error(await r.text());
|
|
5
|
+
return await r.json();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** No-op - cache removed for dev tool responsiveness */
|
|
9
|
+
export function bustCache(p) {
|
|
10
|
+
// No cache to bust
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function postJSON(p, body, signal) {
|
|
14
|
+
const r = await fetch(p, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body), signal });
|
|
15
|
+
const txt = await r.text();
|
|
16
|
+
if (!r.ok) throw new Error(txt.slice(0, 120));
|
|
17
|
+
try { return JSON.parse(txt); } catch { throw new Error('Bad response: ' + txt.slice(0, 80)); }
|
|
18
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
export function renderStatusBadge(liveness, ageSec) {
|
|
2
|
+
if (liveness === "online")
|
|
3
|
+
return '<span title="● online — heartbeat <90s" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 5px var(--green);margin-right:4px;flex-shrink:0;"></span>';
|
|
4
|
+
if (liveness === "stale")
|
|
5
|
+
return (
|
|
6
|
+
'<span title="● stale — last seen >' +
|
|
7
|
+
(ageSec || "?") +
|
|
8
|
+
's ago" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:#f59e0b;margin-right:4px;flex-shrink:0;"></span>'
|
|
9
|
+
);
|
|
10
|
+
if (liveness === "offline")
|
|
11
|
+
return '<span title="● offline — no heartbeat in 5min" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--red-hi);margin-right:4px;flex-shrink:0;"></span>';
|
|
12
|
+
return '<span title="● unknown — never seen" style="display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--text-3);margin-right:4px;flex-shrink:0;"></span>';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function showLoading(el, msg) {
|
|
16
|
+
if (el)
|
|
17
|
+
el.innerHTML =
|
|
18
|
+
'<div class="meta" style="padding:20px;">' +
|
|
19
|
+
(msg || "Loading\u2026") +
|
|
20
|
+
"</div>";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function showEmpty(el, msg) {
|
|
24
|
+
if (el)
|
|
25
|
+
el.innerHTML =
|
|
26
|
+
'<div class="meta" style="padding:20px;">' +
|
|
27
|
+
(msg || "No items found.") +
|
|
28
|
+
"</div>";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function showError(el, msg) {
|
|
32
|
+
if (el)
|
|
33
|
+
el.innerHTML =
|
|
34
|
+
'<div class="meta" style="padding:20px;color:var(--red-hi);">' +
|
|
35
|
+
(msg || "An error occurred.") +
|
|
36
|
+
"</div>";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function escHtml(s) {
|
|
40
|
+
return String(s ?? "")
|
|
41
|
+
.replace(/&/g, "&")
|
|
42
|
+
.replace(/</g, "<")
|
|
43
|
+
.replace(/>/g, ">")
|
|
44
|
+
.replace(/"/g, """)
|
|
45
|
+
.replace(/'/g, "'");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function showNotification(msg, type) {
|
|
49
|
+
const d = document.createElement("div");
|
|
50
|
+
d.className =
|
|
51
|
+
"notification" +
|
|
52
|
+
(type === "error" || type === true
|
|
53
|
+
? " error"
|
|
54
|
+
: type === "warning"
|
|
55
|
+
? " warning"
|
|
56
|
+
: "");
|
|
57
|
+
d.setAttribute("role", "alert");
|
|
58
|
+
d.setAttribute("aria-live", "polite");
|
|
59
|
+
d.textContent = msg;
|
|
60
|
+
document.body.appendChild(d);
|
|
61
|
+
setTimeout(() => d.remove(), 4500);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function fmt(ts) {
|
|
65
|
+
try {
|
|
66
|
+
return new Date(ts).toLocaleTimeString();
|
|
67
|
+
} catch {
|
|
68
|
+
return String(ts);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function createdAt(info) {
|
|
73
|
+
return (info && info.time && info.time.created) || "";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function appendChatBubble(
|
|
77
|
+
role,
|
|
78
|
+
text,
|
|
79
|
+
fallbackModel,
|
|
80
|
+
fallbackReason,
|
|
81
|
+
primaryModel,
|
|
82
|
+
engineUsed,
|
|
83
|
+
sourceInfo,
|
|
84
|
+
bubbleOptions,
|
|
85
|
+
) {
|
|
86
|
+
const box = document.getElementById("chatMessages");
|
|
87
|
+
if (!box) return;
|
|
88
|
+
const isUser = role === "user";
|
|
89
|
+
const isHistoryRender = Boolean(sourceInfo);
|
|
90
|
+
const forceAppend =
|
|
91
|
+
bubbleOptions &&
|
|
92
|
+
typeof bubbleOptions === "object" &&
|
|
93
|
+
bubbleOptions.force === true;
|
|
94
|
+
if (!isUser && !forceAppend) {
|
|
95
|
+
const last = box.lastElementChild;
|
|
96
|
+
if (last && last.children.length >= 2) {
|
|
97
|
+
const lastBubbleText = last.children[1].textContent;
|
|
98
|
+
if (lastBubbleText.trim() === String(text).trim()) return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const div = document.createElement("div");
|
|
102
|
+
div.style.cssText =
|
|
103
|
+
"display:flex;flex-direction:column;align-items:" +
|
|
104
|
+
(isUser ? "flex-end" : "flex-start") +
|
|
105
|
+
";gap:4px;";
|
|
106
|
+
const labelEl = document.createElement("div");
|
|
107
|
+
labelEl.style.cssText =
|
|
108
|
+
"font-size:11px;color:var(--text-3);padding:0 6px;display:flex;align-items:center;gap:6px;";
|
|
109
|
+
const cl = window._crewLeadInfo || { emoji: "🧠", name: "crew-lead" };
|
|
110
|
+
|
|
111
|
+
// If sourceInfo provided (from history), show source indicator instead of default
|
|
112
|
+
if (sourceInfo) {
|
|
113
|
+
let agentName = "crew-lead";
|
|
114
|
+
if (isUser) {
|
|
115
|
+
agentName = "You";
|
|
116
|
+
} else if (sourceInfo.agentName) {
|
|
117
|
+
agentName = sourceInfo.agentName;
|
|
118
|
+
} else if (sourceInfo.agent) {
|
|
119
|
+
agentName = sourceInfo.agent;
|
|
120
|
+
} else if (sourceInfo.source === "cli") {
|
|
121
|
+
agentName = sourceInfo.engine || "cli";
|
|
122
|
+
} else if (sourceInfo.source === "sub-agent") {
|
|
123
|
+
agentName = "sub-agent";
|
|
124
|
+
} else if (sourceInfo.source === "agent") {
|
|
125
|
+
agentName = sourceInfo.targetAgent || "agent";
|
|
126
|
+
} else if (sourceInfo.source === "dashboard") {
|
|
127
|
+
agentName = "crew-lead";
|
|
128
|
+
}
|
|
129
|
+
const engineLabel =
|
|
130
|
+
!isUser && sourceInfo.engine && sourceInfo.engine !== agentName
|
|
131
|
+
? ` · ${sourceInfo.engine}`
|
|
132
|
+
: "";
|
|
133
|
+
labelEl.textContent = `${sourceInfo.emoji || "🤖"} ${agentName}${engineLabel}`;
|
|
134
|
+
|
|
135
|
+
// Add timestamp as a separate subdued span
|
|
136
|
+
const ts = document.createElement("span");
|
|
137
|
+
ts.style.cssText = "opacity:0.6;";
|
|
138
|
+
ts.textContent = sourceInfo.timestamp ? " · " + sourceInfo.timestamp : "";
|
|
139
|
+
labelEl.appendChild(ts);
|
|
140
|
+
} else {
|
|
141
|
+
const displayName = isUser
|
|
142
|
+
? "You"
|
|
143
|
+
: role === "assistant"
|
|
144
|
+
? cl.emoji + " " + cl.name
|
|
145
|
+
: role;
|
|
146
|
+
labelEl.textContent = displayName;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Show model badge - always for non-user messages
|
|
150
|
+
if (!isUser) {
|
|
151
|
+
const modelToShow = fallbackModel || primaryModel;
|
|
152
|
+
if (modelToShow) {
|
|
153
|
+
const badge = document.createElement("span");
|
|
154
|
+
if (fallbackModel) {
|
|
155
|
+
badge.title =
|
|
156
|
+
"Primary failed (" +
|
|
157
|
+
(fallbackReason || "error") +
|
|
158
|
+
") — running on fallback";
|
|
159
|
+
badge.style.cssText =
|
|
160
|
+
"font-size:10px;padding:1px 6px;border-radius:999px;background:rgba(245,158,11,0.15);color:#f59e0b;border:1px solid rgba(245,158,11,0.3);cursor:default;";
|
|
161
|
+
badge.textContent = "⚡ fallback: " + fallbackModel;
|
|
162
|
+
} else {
|
|
163
|
+
badge.title = "Primary model";
|
|
164
|
+
badge.style.cssText =
|
|
165
|
+
"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;";
|
|
166
|
+
badge.textContent = modelToShow;
|
|
167
|
+
}
|
|
168
|
+
labelEl.appendChild(badge);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Show engine badge if available (for coding agents using CLIs)
|
|
172
|
+
if (engineUsed) {
|
|
173
|
+
const engineColors = {
|
|
174
|
+
claude: "#e07a5f",
|
|
175
|
+
codex: "#8338ec",
|
|
176
|
+
cursor: "#3d405b",
|
|
177
|
+
opencode: "#06d6a0",
|
|
178
|
+
gemini: "#4285f4",
|
|
179
|
+
"docker-sandbox": "#0db7ed",
|
|
180
|
+
};
|
|
181
|
+
const engineLabels = {
|
|
182
|
+
claude: "🤖 Claude Code",
|
|
183
|
+
codex: "🟣 Codex",
|
|
184
|
+
cursor: "🖱 Cursor",
|
|
185
|
+
opencode: "⚡ OpenCode",
|
|
186
|
+
gemini: "✨ Gemini",
|
|
187
|
+
"docker-sandbox": "🐳 Docker",
|
|
188
|
+
};
|
|
189
|
+
const engineBadge = document.createElement("span");
|
|
190
|
+
engineBadge.title =
|
|
191
|
+
"Executed by " + (engineLabels[engineUsed] || engineUsed);
|
|
192
|
+
engineBadge.style.cssText =
|
|
193
|
+
"font-size:10px;padding:1px 6px;border-radius:999px;color:#fff;background:" +
|
|
194
|
+
(engineColors[engineUsed] || "var(--text-3)") +
|
|
195
|
+
";cursor:default;";
|
|
196
|
+
engineBadge.textContent = engineLabels[engineUsed] || engineUsed;
|
|
197
|
+
labelEl.appendChild(engineBadge);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const bubble = document.createElement("div");
|
|
202
|
+
const assistantBg = "var(--surface-2)";
|
|
203
|
+
const assistantText = "var(--text-2)";
|
|
204
|
+
const assistantBorder = "var(--border)";
|
|
205
|
+
bubble.style.cssText =
|
|
206
|
+
"max-width:80%;padding:10px 14px;border-radius:" +
|
|
207
|
+
(isUser ? "14px 14px 4px 14px" : "14px 14px 14px 4px") +
|
|
208
|
+
";background:" +
|
|
209
|
+
(isUser ? "var(--purple)" : assistantBg) +
|
|
210
|
+
";color:" +
|
|
211
|
+
(isUser ? "#fff" : assistantText) +
|
|
212
|
+
";font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid " +
|
|
213
|
+
(isUser ? "var(--border)" : assistantBorder) +
|
|
214
|
+
";";
|
|
215
|
+
bubble.textContent = text;
|
|
216
|
+
div.appendChild(labelEl);
|
|
217
|
+
div.appendChild(bubble);
|
|
218
|
+
box.appendChild(div);
|
|
219
|
+
box.scrollTop = box.scrollHeight;
|
|
220
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Shared in-memory state — mutate via the exported object properties
|
|
2
|
+
// Restored from sessionStorage on page load to survive refresh
|
|
3
|
+
|
|
4
|
+
const STORAGE_KEY = 'crewswarm_ui_state';
|
|
5
|
+
|
|
6
|
+
function loadSaved() {
|
|
7
|
+
try {
|
|
8
|
+
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
9
|
+
return raw ? JSON.parse(raw) : {};
|
|
10
|
+
} catch { return {}; }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const saved = loadSaved();
|
|
14
|
+
|
|
15
|
+
export const state = {
|
|
16
|
+
// OpenCode session selection (Sessions tab)
|
|
17
|
+
selected: saved.selected || null,
|
|
18
|
+
|
|
19
|
+
// Selected CLI engine for Sessions tab (opencode, claude, codex, gemini, crew-cli)
|
|
20
|
+
selectedEngine: saved.selectedEngine || 'opencode',
|
|
21
|
+
|
|
22
|
+
// Agent list (loaded from /api/agents)
|
|
23
|
+
agents: saved.agents || [],
|
|
24
|
+
|
|
25
|
+
// Active chat project
|
|
26
|
+
chatActiveProjectId: saved.chatActiveProjectId || '',
|
|
27
|
+
|
|
28
|
+
// Active shared channel/project for the Swarm tab
|
|
29
|
+
swarmChatProjectId: saved.swarmChatProjectId || '',
|
|
30
|
+
|
|
31
|
+
// Project registry cache (populated by loadProjects)
|
|
32
|
+
projectsData: saved.projectsData || {},
|
|
33
|
+
|
|
34
|
+
// Active tab (for scroll restoration)
|
|
35
|
+
activeTab: saved.activeTab || 'chat',
|
|
36
|
+
|
|
37
|
+
// Per-tab scroll positions { tabName: scrollTop }
|
|
38
|
+
scrollPositions: saved.scrollPositions || {},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Persist current state to sessionStorage (call after meaningful state changes). */
|
|
42
|
+
export function persistState() {
|
|
43
|
+
try {
|
|
44
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify({
|
|
45
|
+
selected: state.selected,
|
|
46
|
+
selectedEngine: state.selectedEngine,
|
|
47
|
+
chatActiveProjectId: state.chatActiveProjectId,
|
|
48
|
+
swarmChatProjectId: state.swarmChatProjectId,
|
|
49
|
+
projectsData: state.projectsData,
|
|
50
|
+
activeTab: state.activeTab,
|
|
51
|
+
scrollPositions: state.scrollPositions,
|
|
52
|
+
// Don't persist agents list — it's large and gets stale
|
|
53
|
+
}));
|
|
54
|
+
} catch { /* quota exceeded or private mode — ignore */ }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Save scroll position for the current active tab. */
|
|
58
|
+
export function saveScrollPosition(tabName) {
|
|
59
|
+
const main = document.querySelector('.view.active');
|
|
60
|
+
if (main) {
|
|
61
|
+
state.scrollPositions[tabName || state.activeTab] = main.scrollTop;
|
|
62
|
+
persistState();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Restore scroll position for a tab after re-render. */
|
|
67
|
+
export function restoreScrollPosition(tabName) {
|
|
68
|
+
const pos = state.scrollPositions[tabName];
|
|
69
|
+
if (pos != null) {
|
|
70
|
+
requestAnimationFrame(() => {
|
|
71
|
+
const main = document.querySelector('.view.active');
|
|
72
|
+
if (main) main.scrollTop = pos;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const AGENT_RANK = {
|
|
78
|
+
'crew-lead': 0,
|
|
79
|
+
'crew-orchestrator': 1, 'orchestrator': 1, 'crew-main': 2,
|
|
80
|
+
'crew-pm': 3, 'crew-architect': 4,
|
|
81
|
+
'crew-coder': 5, 'crew-coder-back': 6, 'crew-coder-front': 7, 'crew-frontend': 8,
|
|
82
|
+
'crew-ml': 9, 'crew-fixer': 10,
|
|
83
|
+
'crew-qa': 11, 'crew-security': 12,
|
|
84
|
+
'crew-researcher': 13, 'crew-copywriter': 14, 'crew-seo': 15,
|
|
85
|
+
'crew-github': 16, 'crew-db-migrator': 17,
|
|
86
|
+
'crew-telegram': 18, 'crew-mega': 19,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export function sortAgents(arr) {
|
|
90
|
+
return (arr || []).sort((a, b) => (AGENT_RANK[a.id] ?? 50) - (AGENT_RANK[b.id] ?? 50));
|
|
91
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Manager - Tracks and controls active tasks/agents
|
|
3
|
+
* Allows individual stop controls and concurrent operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class TaskManager {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.activeTasks = new Map(); // taskId -> { agent, controller, startTime, status, type }
|
|
9
|
+
this.listeners = new Set();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Register a new task with abort controller
|
|
14
|
+
* @param {string} taskId - Unique task identifier
|
|
15
|
+
* @param {object} details - { agent, type, description, controller }
|
|
16
|
+
*/
|
|
17
|
+
registerTask(taskId, details) {
|
|
18
|
+
this.activeTasks.set(taskId, {
|
|
19
|
+
...details,
|
|
20
|
+
startTime: Date.now(),
|
|
21
|
+
status: 'running',
|
|
22
|
+
});
|
|
23
|
+
this.notifyListeners();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Stop a specific task by ID
|
|
28
|
+
* @param {string} taskId
|
|
29
|
+
*/
|
|
30
|
+
stopTask(taskId) {
|
|
31
|
+
const task = this.activeTasks.get(taskId);
|
|
32
|
+
if (!task) return false;
|
|
33
|
+
|
|
34
|
+
if (task.controller) {
|
|
35
|
+
task.controller.abort();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
task.status = 'stopped';
|
|
39
|
+
this.activeTasks.delete(taskId);
|
|
40
|
+
this.notifyListeners();
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Mark task as completed
|
|
46
|
+
* @param {string} taskId
|
|
47
|
+
*/
|
|
48
|
+
completeTask(taskId) {
|
|
49
|
+
const task = this.activeTasks.get(taskId);
|
|
50
|
+
if (!task) return;
|
|
51
|
+
|
|
52
|
+
task.status = 'completed';
|
|
53
|
+
this.activeTasks.delete(taskId);
|
|
54
|
+
this.notifyListeners();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Mark task as failed
|
|
59
|
+
* @param {string} taskId
|
|
60
|
+
* @param {string} error
|
|
61
|
+
*/
|
|
62
|
+
failTask(taskId, error) {
|
|
63
|
+
const task = this.activeTasks.get(taskId);
|
|
64
|
+
if (!task) return;
|
|
65
|
+
|
|
66
|
+
task.status = 'failed';
|
|
67
|
+
task.error = error;
|
|
68
|
+
this.activeTasks.delete(taskId);
|
|
69
|
+
this.notifyListeners();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get all active tasks
|
|
74
|
+
*/
|
|
75
|
+
getActiveTasks() {
|
|
76
|
+
return Array.from(this.activeTasks.entries()).map(([id, task]) => ({
|
|
77
|
+
id,
|
|
78
|
+
...task,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check if a specific agent is currently busy
|
|
84
|
+
* @param {string} agent
|
|
85
|
+
*/
|
|
86
|
+
isAgentBusy(agent) {
|
|
87
|
+
return Array.from(this.activeTasks.values()).some(
|
|
88
|
+
(task) => task.agent === agent && task.status === 'running'
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Stop all tasks
|
|
94
|
+
*/
|
|
95
|
+
stopAll() {
|
|
96
|
+
for (const [taskId] of this.activeTasks) {
|
|
97
|
+
this.stopTask(taskId);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Stop all tasks for a specific agent
|
|
103
|
+
* @param {string} agent
|
|
104
|
+
*/
|
|
105
|
+
stopAgent(agent) {
|
|
106
|
+
for (const [taskId, task] of this.activeTasks) {
|
|
107
|
+
if (task.agent === agent) {
|
|
108
|
+
this.stopTask(taskId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Subscribe to task changes
|
|
115
|
+
* @param {function} callback
|
|
116
|
+
*/
|
|
117
|
+
subscribe(callback) {
|
|
118
|
+
this.listeners.add(callback);
|
|
119
|
+
return () => this.listeners.delete(callback);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
notifyListeners() {
|
|
123
|
+
for (const listener of this.listeners) {
|
|
124
|
+
try {
|
|
125
|
+
listener(this.getActiveTasks());
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error('TaskManager listener error:', err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Singleton instance
|
|
134
|
+
export const taskManager = new TaskManager();
|
|
Binary file
|