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 @@
|
|
|
1
|
+
import{a as e,b as t,s as n,g as a,e as o,c as r,d as i,p as s}from"./core-utils-CAVnDoe1.js";let l=()=>{},d=()=>{},c=[],m=!1,u=[],p=0,g=null,w=null,y=null;function h(e){var t;const n=document.getElementById("swarmChatMessages");n&&(n.firstElementChild&&(null==(t=n.firstElementChild.textContent)?void 0:t.includes("No shared channel messages yet."))&&(n.innerHTML=""),c.push(e),n.insertAdjacentHTML("beforeend",$(e)),n.scrollTop=n.scrollHeight)}function f(){var e;null==(e=document.getElementById("swarm-typing-wrapper"))||e.remove()}const v={dashboard:{emoji:"🧠",label:"crew-lead"},agent:{emoji:"🤖",label:"agent"},"sub-agent":{emoji:"👷",label:"sub-agent"},cli:{emoji:"⚡",label:"cli"},discord:{emoji:"🎮",label:"discord"},system:{emoji:"🛰",label:"system"}};function x(e={}){l=e.hideAllViews||l,d=e.setNavActive||d,b()}function b(){if(m)return;const r=document.getElementById("swarmChatProject"),i=document.getElementById("swarmChatRefresh"),l=document.getElementById("swarmAutonomyBtn"),d=document.getElementById("swarmChatForm"),g=document.getElementById("swarmChatInput"),w=document.getElementById("swarmChatSend"),y=document.getElementById("swarmChatMessages");r&&i&&d&&g&&w&&y&&(m=!0,r.addEventListener("change",async()=>{e.swarmChatProjectId=r.value||"general",t(),await j()}),i.addEventListener("click",()=>{C().then(j).catch(e=>{n(`Failed to refresh Swarm: ${e.message}`,"error")})}),null==l||l.addEventListener("click",()=>{(async function(){const e=await a("/api/settings/autonomous-mentions"),t=await s("/api/settings/autonomous-mentions",{enabled:!e.enabled});n("Swarm autonomy "+(t.enabled?"ENABLED 🕸":"DISABLED")),await E()})().catch(e=>{n(`Failed to toggle autonomy: ${e.message}`,"error")})}),d.addEventListener("submit",e=>{e.preventDefault(),e.stopPropagation(),T()}),w.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),T()}),g.addEventListener("keydown",e=>{const t=document.getElementById("swarmMentionMenu");if(t&&"block"===t.style.display&&("Enter"===e.key||"Tab"===e.key)){const n=t.firstElementChild;if(n)return e.preventDefault(),void n.click()}"Enter"!==e.key||e.shiftKey||(e.preventDefault(),T())}),g.addEventListener("input",()=>{(async function(){const e=document.getElementById("swarmChatInput"),t=document.getElementById("swarmMentionMenu"),n=document.getElementById("swarmMentionHint");if(!e||!t||!n)return;const o=e.value||"",r=e.selectionStart||0,i=o.slice(0,r).match(/(^|\s)@([a-zA-Z0-9_-]*)$/);if(!i)return t.style.display="none",void(n.style.display="none");const s=(i[2]||"").toLowerCase(),l=(await async function(e=!1){const t=Date.now();if(!e&&u.length&&t-p<3e4)return u;const n=((await a("/api/chat-participants")).participants||[]).filter(e=>e.id).sort((e,t)=>e.id.localeCompare(t.id)).map(e=>({id:e.id,name:"cli"===e.kind?`${e.runtime} runtime`:e.kind,role:e.kind,kind:e.kind}));return u=n,p=t,n}()).filter(e=>e.id.toLowerCase().includes(s)).slice(0,8);if(!l.length)return t.style.display="none",void(n.style.display="none");t.style.display="block",t.innerHTML="",l.forEach(a=>{const s=document.createElement("div");s.style.cssText="padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--border);",s.onmouseenter=()=>{s.style.background="var(--bg-hover)"},s.onmouseleave=()=>{s.style.background=""},s.innerHTML=`<span style="color:var(--accent);font-weight:600;">@${a.id}</span> <span style="color:var(--text-3);">${a.name||a.role||"agent"}</span>`,s.onclick=()=>{const s=r-i[0].length+i[1].length,l=`@${a.id} `;e.value=o.slice(0,s)+l+o.slice(r);const d=s+l.length;e.selectionStart=e.selectionEnd=d,e.focus(),t.style.display="none",n.style.display="block",n.textContent="crew-lead"===a.id?"Mention target: @crew-lead. Use this for notes or routing guidance.":`Mention target: @${a.id}. Use a specific work order if you want execution.`},t.appendChild(s)}),n.style.display="block",n.textContent=s?`Matching participants for @${s}`:"Type a participant, e.g. @crew-lead for notes or @crew-coder with a specific work order."})().catch(()=>{})}),y.addEventListener("click",e=>{const t=e.target.closest("[data-swarm-message-id]");t&&function(e){var t;const n=document.getElementById("swarmTracePanel");if(!n)return;const a=c.find(t=>t.id===e);if(!a)return;const r=a.metadata||{},i=[["messageId",a.id],["source",a.source],["agent",a.agent||null],["taskId",r.taskId||null],["threadId",a.threadId||r.originThreadId||null],["parentId",a.parentId||r.originMessageId||null],["originProjectId",r.originProjectId||null],["originChannel",r.originChannel||r.channel||null],["triggeredBy",r.triggeredBy||null],["mentionedBy",r.mentionedBy||null]].filter(([,e])=>e);n.style.display="block",n.innerHTML=`\n <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px;">\n <strong style="color:var(--text-1);">Trace</strong>\n <button type="button" id="swarmTraceClose" class="btn-ghost" style="font-size:11px;padding:4px 8px;">Close</button>\n </div>\n <div style="display:grid;grid-template-columns:140px 1fr;gap:6px 10px;">\n ${i.map(([e,t])=>`<div style="color:var(--text-3);">${o(e)}</div><div style="font-family:monospace;word-break:break-all;">${o(String(t))}</div>`).join("")}\n </div>\n `,null==(t=n.querySelector("#swarmTraceClose"))||t.addEventListener("click",B,{once:!0})}(t.dataset.swarmMessageId)}))}async function I(){var n,a;b(),l(),null==(n=document.getElementById("swarmChatView"))||n.classList.add("active"),d("navSwarmChat"),e.activeTab="swarm-chat",e.swarmChatProjectId||(e.swarmChatProjectId=e.chatActiveProjectId||"general"),t(),await C(),await E(),await j(),null==(a=document.getElementById("swarmChatInput"))||a.focus()}async function E(){const e=document.getElementById("swarmAutonomyBtn"),t=document.getElementById("swarmAutonomyStatus"),n=document.getElementById("swarmChatInput"),o=!1!==(await a("/api/settings/autonomous-mentions")).enabled;e&&(e.textContent=o?"🕸 Auto ON":"⚫ Auto OFF",e.style.background=o?"rgba(52,211,153,0.15)":"",e.style.borderColor=o?"rgba(52,211,153,0.3)":"",e.style.color=o?"var(--green)":""),t&&(t.textContent=o?"Autonomous routing is live in this room. @mentions can dispatch agents or run CLI participants.":"Autonomous routing is off. @mentions stay visible in chat, but nothing auto-runs."),n&&(n.placeholder=o?"Talk in-channel. Use @crew-* or @codex/@cursor/@claude/@opencode/@gemini/@crew-cli to route work.":"Autonomy is off. @mentions are informational until you turn routing back on.")}async function C(){const n=document.getElementById("swarmChatProject");if(!n)return;const r=e.swarmChatProjectId||e.chatActiveProjectId||"general",i=[{id:"general",name:"General"}];try{const e=await a("/api/projects");for(const t of e.projects||[])i.push({id:t.id,name:t.name||t.id})}catch{}n.innerHTML=i.map(e=>{const t=e.id===r?" selected":"";return`<option value="${o(e.id)}"${t}>${o(e.name)}</option>`}).join(""),e.swarmChatProjectId=n.value||"general",t();const s=document.getElementById("swarmChatHint");if(s){const t=i.find(t=>t.id===e.swarmChatProjectId);s.textContent="general"===e.swarmChatProjectId?"Shared global room. Same unified history store as Chat.":`Project channel for ${(null==t?void 0:t.name)||e.swarmChatProjectId}. Same history store as Chat.`}}async function j(){const t=document.getElementById("swarmChatMessages");if(!t)return;const n=e.swarmChatProjectId||"general";t.innerHTML="";try{const e=(await a(`/api/crew-lead/project-messages?projectId=${encodeURIComponent(n)}&limit=300&excludeDirect=true`)).messages||[];if(c=e,!e.length)return B(),void r(t,"No shared channel messages yet.");t.innerHTML=e.map($).join(""),t.scrollTop=t.scrollHeight}catch(o){i(t,`Failed to load shared channel: ${o.message}`)}}function $(e){var t,n,a,r,i,s,l,d,c,m;const u=v[e.source]||{emoji:"📝",label:e.source||"message"},p="user"===e.role,g=(null==(t=e.metadata)?void 0:t.agentEmoji)||(p?"👤":u.emoji),w=(null==(n=e.metadata)?void 0:n.agentName)||e.agent||(p?"You":u.label),y=new Date(e.ts||Date.now()).toLocaleTimeString(),h=[];return(null==(a=e.metadata)?void 0:a.channel)&&h.push(`#${e.metadata.channel}`),(null==(r=e.metadata)?void 0:r.directChat)&&h.push("direct"),(null==(i=e.metadata)?void 0:i.engine)&&h.push(e.metadata.engine),Array.isArray(null==(s=e.metadata)?void 0:s.mentions)&&e.metadata.mentions.forEach(e=>h.push(`@${e}`)),("mention"===(null==(l=e.metadata)?void 0:l.triggeredBy)||(null==(d=e.metadata)?void 0:d.autonomous))&&h.push("@mention"),(e.parentId||(null==(c=e.metadata)?void 0:c.originMessageId))&&h.push("linked"),(e.threadId||(null==(m=e.metadata)?void 0:m.originThreadId))&&h.push("thread"),`\n <div data-swarm-message-id="${o(e.id||"")}" style="display:flex;flex-direction:column;align-items:${p?"flex-end":"flex-start"};gap:4px;margin-bottom:10px;cursor:pointer;">\n <div style="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;gap:6px;align-items:center;flex-wrap:wrap;">\n <span>${o(g)} ${o(w)}</span>\n <span style="opacity:0.7;">${o(y)}</span>\n ${h.map(e=>`<span style="padding:1px 6px;border-radius:999px;background:var(--bg-card2);border:1px solid var(--border);">${o(e)}</span>`).join("")}\n </div>\n <div style="max-width:84%;padding:10px 14px;border-radius:${p?"14px 14px 4px 14px":"14px 14px 14px 4px"};background:${p?"var(--purple)":"var(--surface-2)"};color:${p?"#fff":"var(--text-2)"};font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid var(--border);">${o(e.content||"")}</div>\n </div>\n `}function k(t){const n=document.getElementById("swarmChatMessages");if(!n)return!1;const a=e.swarmChatProjectId||"general",o=`swarm-${a}`,r=e=>e&&"general"!==e?e:"general";if(r(t.projectId)!==r(a)||t.sessionId!==o)return!1;if("chat_stream"===t.type){f();let e=document.getElementById("swarm-streaming-bubble");if(!e){const a=document.createElement("div");a.id="swarm-streaming-wrapper",a.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;margin-bottom:10px;";const o=document.createElement("div");o.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;display:flex;gap:6px;align-items:center;flex-wrap:wrap;";const r=t.agentName||t.agentEmoji?{name:t.agentName||t.agent||"agent",emoji:t.agentEmoji||"🤖"}:y||window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"};o.textContent=`${r.emoji} ${r.name}`,e=document.createElement("div"),e.id="swarm-streaming-bubble",e.style.cssText="max-width:84%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid var(--border);",e._textNode=document.createTextNode(""),e.appendChild(e._textNode),a.appendChild(o),a.appendChild(e),n.appendChild(a)}return e._textNode.textContent+=t.token||"",n.scrollTop=n.scrollHeight,!0}if("chat_message"!==t.type)return!1;const i=document.getElementById("swarm-streaming-wrapper");if(i&&"assistant"===t.role&&i.remove(),"assistant"===t.role&&(f(),y=null),"user"===t.role){if(t.content===g)return!0;g=t.content}else if("assistant"===t.role){if(t.content===w)return!0;w=t.content}const s="assistant"===t.role?t.agent||("agent"===t.source||"cli"===t.source?null:"crew-lead"):null;return h({id:`live-${t.role}-${Date.now()}`,ts:Date.now(),source:t.source||"dashboard",role:t.role,content:t.content||"",agent:s,metadata:"assistant"===t.role?{agentName:t.agentName||("crew-lead"===s?(window._crewLeadInfo||{}).name||"crew-lead":s||"agent"),agentEmoji:t.agentEmoji||("crew-lead"===s?(window._crewLeadInfo||{}).emoji||"🧠":"🤖"),model:t.model||null,...t.directChat?{directChat:!0}:{},...t.multiDirect?{multiDirect:!0}:{}}:{agentName:"You",agentEmoji:"👤"}}),!0}function B(){const e=document.getElementById("swarmTracePanel");e&&(e.style.display="none",e.innerHTML="")}async function T(){var t;const a=document.getElementById("swarmChatInput"),r=document.getElementById("swarmChatSend");if(!a||!r)return;const i=a.value.trim();if(!i)return;const l=e.swarmChatProjectId||"general";r.disabled=!0,a.value="",y=function(e=""){const t=Array.from(String(e||"").matchAll(/@([a-zA-Z0-9_-]+)/g)).map(e=>e[1]);if(1!==t.length)return null;const n=t[0],a=u.find(e=>e.id===n)||u.find(e=>e.id===`crew-${n}`);return a?{id:a.id,name:a.name||a.displayName||a.id,emoji:a.emoji||"🤖"}:{id:n,name:n,emoji:"🤖"}}(i),h({id:`local-user-${Date.now()}`,ts:Date.now(),source:"dashboard",role:"user",content:i,agent:null,metadata:{agentName:"You",agentEmoji:"👤"}}),g=i,function(e=null){const t=document.getElementById("swarmChatMessages");if(!t||document.getElementById("swarm-typing-wrapper"))return;const n=e||y||window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"},a=document.createElement("div");a.id="swarm-typing-wrapper",a.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;margin-bottom:10px;",a.innerHTML=`\n <div style="font-size:11px;color:var(--text-3);padding:0 6px;">${o(n.emoji)} ${o(n.name)}</div>\n <div style="max-width:84%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);font-size:14px;line-height:1.5;border:1px solid var(--border);font-style:italic;opacity:0.8;">thinking...</div>\n `,t.appendChild(a),t.scrollTop=t.scrollHeight}(y);try{const e=await s("/api/chat/unified",{message:i,sessionId:`swarm-${l}`,projectId:l,channelMode:!0});if(Array.isArray(null==e?void 0:e.replies)&&e.replies.length){f();for(const t of e.replies)h({id:`local-assistant-${t.agent}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,ts:Date.now(),source:"agent",role:"assistant",content:t.reply||"",agent:t.agent||null,metadata:{agentName:t.agentName||t.agent||"agent",agentEmoji:t.agentEmoji||"🤖",directChat:!0,multiDirect:!0}});return w=(null==(t=e.replies[e.replies.length-1])?void 0:t.reply)||null,void(y=null)}if((null==e?void 0:e.reply)&&e.reply!==w&&!document.getElementById("swarm-streaming-wrapper")){f();const t=e.agent||e.routedTo||"crew-lead",n=e.agentName||(null==y?void 0:y.name)||("crew-lead"===t?(window._crewLeadInfo||{}).name||"crew-lead":t),a=e.agentEmoji||(null==y?void 0:y.emoji)||("crew-lead"===t?(window._crewLeadInfo||{}).emoji||"🧠":"🤖");h({id:`local-assistant-${Date.now()}`,ts:Date.now(),source:e.directChat?"agent":"dashboard",role:"assistant",content:e.reply,agent:t,metadata:{agentName:n,agentEmoji:a,...e.directChat?{directChat:!0}:{}}}),w=e.reply,y=null}}catch(d){f(),y=null,n(`Swarm send failed: ${d.message}`,"error"),h({id:`local-error-${Date.now()}`,ts:Date.now(),source:"system",role:"assistant",content:`Failed to send: ${d.message}`,agent:"crew-lead",metadata:{agentName:"system",agentEmoji:"🛰"}})}finally{r.disabled=!1,a.focus()}}export{k as h,x as i,I as s};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,b as t,h as n,g as s,e as o,i,j as a,s as r,p as l}from"./core-utils-CAVnDoe1.js";let c=()=>{},d=()=>{};function p({hideAllViews:e,setNavActive:t}={}){c=e||c,d=t||d}let m=e.selected||null,u=e.selectedEngine||"opencode";async function g(){const n=document.getElementById("sessions");n&&(n.innerHTML='<div style="padding:20px;">Loading…</div>');const i=n.parentElement;let a=document.getElementById("engine-selector");a||(a=document.createElement("div"),a.id="engine-selector",a.style.cssText="padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;",a.innerHTML='<label style="font-size:13px;font-weight:500;color:var(--text-2);">CLI:</label><select id="engine-select" style="padding:6px 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg-1);color:var(--text-1);font-size:13px;cursor:pointer;"><option value="opencode">OpenCode</option><option value="claude">Claude Code</option><option value="codex">Codex CLI</option><option value="gemini">Gemini CLI</option><option value="crew-cli">crew-cli</option></select><span style="font-size:12px;color:var(--text-3);margin-left:8px;" id="session-count"></span>',i.insertBefore(a,n),document.getElementById("engine-select").addEventListener("change",n=>{u=n.target.value,e.selectedEngine=u,t(),m=null,g()}));const r=document.getElementById("engine-select");r&&(r.value=u);try{let n=function(e){if(!e||"string"!=typeof e)return null;const t=e.match(/\[?(crew-\w+)\]?/);return t?t[1]:null},i=function(e){return e&&"string"==typeof e?/\bFixer\b|fixer\s+task|fix\s+.*\.py|syntax\s+error/i.test(e)?"fixer":/\bQA\b|qa\s+audit|audit:/i.test(e)?"qa":/\bPM\b|crew-pm|roadmap\b/i.test(e)?"pm":/\bCoder\b|coder\s+task|frontend\b|backend\b/i.test(e)?"coder":/\bSecurity\b|security\s+review/i.test(e)?"security":/\bCopywriter\b|copy\s+task/i.test(e)?"copywriter":null:null},a=function(e){return e&&/^[a-z]+-[a-z]+$/.test(e)&&!e.startsWith("crew-")};const r=e.chatActiveProjectId||"general",l="/api/engine-sessions?engine="+encodeURIComponent(u)+"&projectId="+encodeURIComponent(r),c=await s(l),d=c.sessions||c||[],p=document.getElementById("sessions"),f=document.getElementById("session-count");if(p.innerHTML="",!d.length){const e={opencode:"OpenCode",claude:"Claude Code",codex:"Codex CLI",gemini:"Gemini CLI","crew-cli":"crew-cli"}[u]||u;return p.innerHTML=`<div style="padding:20px 16px;"><div style="font-size:13px;font-weight:600;margin-bottom:6px;">No ${e} sessions</div><div style="font-size:12px;color:var(--text-3);line-height:1.6;">No session history found for <strong>${e}</strong>. Run a task using this engine to see sessions here.</div></div>`,void(f&&(f.textContent=""))}f&&(f.textContent=`${d.length} session${1!==d.length?"s":""}`),!m&&d[0]&&(m=d[0].id),d.forEach(s=>{const r=document.createElement("div"),l=s.id||s.sessionId||"";r.className="row"+(l===m?" active":""),r.onclick=()=>{m=l,e.selected=l,t(),g(),x()};let c=s.title||s.slug||l,d=s.directory||"",f="";if("opencode"===u){const e=n(c),t=i(c),o=s.slug||"",r=e||(o&&!a(o)?o:null)||t,l=a(o)?" ("+o+")":"";f=r?"Assigned to: "+r+l:o?"Assigned to: "+o+" (OpenCode session)":""}else"claude"===u?d=s.file?s.file.split("/").pop().replace(".jsonl",""):"":"codex"===u?d=s.file||"":"gemini"===u?d="Project: "+l:"crew-cli"===u&&(f=s.engine+" / "+s.project,d=s.file||"");c.length>80&&(c=c.slice(0,77)+"..."),r.innerHTML="<div><strong>"+o(c)+"</strong></div>"+(d?'<div class="meta">'+o(d)+"</div>":"")+(f?'<div class="meta" style="font-size:11px;color:var(--accent);">'+o(f)+"</div>":""),p.appendChild(r)})}catch(l){const e=document.getElementById("sessions");e&&(e.innerHTML='<div class="meta" style="padding:20px; color:var(--red-hi);">Error loading sessions.</div>')}}async function x(){const e=document.getElementById("messages");if(m)try{if("opencode"===u){const t=await s("/api/messages?session="+encodeURIComponent(m));e.innerHTML="",t.slice(-40).forEach(t=>{const n=(t.parts||[]).filter(e=>"text"===e.type).map(e=>e.text).join("").trim();if(!n)return;const s=document.createElement("div");s.className="msg "+("assistant"===(t.info&&t.info.role)?"a":"u"),s.innerHTML='<div class="meta">'+(t.info&&t.info.role)+" • "+i(a(t.info))+'</div><div class="t"></div>',s.querySelector(".t").textContent=n,e.appendChild(s)})}else{const t={claude:"/api/claude-sessions",codex:"/api/codex-sessions",gemini:"/api/gemini-sessions","crew-cli":"/api/crew-cli-sessions"}[u];if(!t)return void(e.innerHTML='<div class="meta">Engine not supported</div>');const n=await s(t),o=(n.sessions||n||[]).find(e=>e.id===m||e.sessionId===m);if(!o||!o.messages)return void(e.innerHTML='<div class="meta">No messages found</div>');e.innerHTML="",o.messages.slice(-40).forEach(t=>{const n=document.createElement("div");n.className="msg "+("assistant"===t.role?"a":"u");const s=t.ts?new Date(t.ts).toLocaleString():"";n.innerHTML='<div class="meta">'+t.role+(s?" • "+s:"")+'</div><div class="t"></div>',n.querySelector(".t").textContent=t.text||"",e.appendChild(n)})}e.scrollTop=e.scrollHeight}catch(t){e&&(e.innerHTML='<div class="meta">Error: '+t.message+"</div>")}else e&&(e.innerHTML='<div class="meta">No session selected.</div>')}function f(){c(),document.getElementById("sessionsView").classList.add("active"),d("navSwarm"),e.activeTab="swarm",t();const s=document.getElementById("sessions");s&&s.children.length>1?n("swarm"):(g(),x())}let y=!1,v="tasks",h="";const b=new Set(["agent.heartbeat","agent.online","agent.offline"]),w=new Set(["task.dispatched","task.done","task.completed","task.failed","task.cancelled","task.started","task.reply"]);function C(e){if(b.has(e.type))return!1;const t=e.payload||{},n=t.reply||t.prompt||t.message||t.content||"";if(!n||"run_task"===n)return!1;if("tasks"===v&&!w.has(e.type))return!1;if("replies"===v&&!(t.reply||t.message||t.content))return!1;if(h){const t=h.toLowerCase();if(!((e.from||"").toLowerCase().includes(t)||(e.to||"").toLowerCase().includes(t)||n.toLowerCase().includes(t)||(e.type||"").toLowerCase().includes(t)))return!1}return!0}const E={"task.dispatched":{color:"var(--purple)",label:"dispatched"},"task.started":{color:"var(--amber)",label:"started"},"task.done":{color:"var(--green-hi)",label:"done"},"task.completed":{color:"var(--green-hi)",label:"completed"},"task.reply":{color:"var(--accent)",label:"reply"},"task.failed":{color:"var(--red-hi)",label:"failed"},"task.cancelled":{color:"var(--text-3)",label:"cancelled"}};async function L(){if(y)return;const e=document.getElementById("rtMessages"),t=document.getElementById("rtView");if(!e||!t)return;const n=0===e.children.length;if(n){const t=document.createElement("div");t.style.cssText="padding:20px;",t.textContent="Loading…",e.replaceChildren(t)}const o=(await s("/api/rt-messages")).filter(C).slice(-100),i=o.map(e=>{const t=e.payload||{},n=t.reply||t.prompt||t.message||t.content||"";return`${e.type}|${e.from}|${e.to}|${n.slice(0,100)}`}).join("::");if(i===window._rtLastHash&&!n)return;window._rtLastHash=i;const a=()=>t.scrollHeight-t.scrollTop-t.clientHeight<100,r=a(),l=t.scrollTop,c=document.createDocumentFragment();if(o.length){const e=document.createElement("div");e.style.cssText="display:grid;grid-template-columns:auto auto 1fr auto;gap:10px;padding:4px 10px 6px;font-size:10px;font-weight:600;color:var(--text-3);letter-spacing:.06em;text-transform:uppercase;border-bottom:2px solid var(--border);margin-bottom:2px;",["Agent","Phase","Summary","Time"].forEach(t=>{const n=document.createElement("span");n.textContent=t,e.appendChild(n)}),c.appendChild(e),o.forEach(e=>c.appendChild(function(e){const t=e.payload||{},n=t.reply||t.prompt||t.message||t.content||"",s=e.type||"",o=E[s],i=e.ts?new Date(e.ts).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"",a=n.split("\n").map(e=>e.trim()).find(e=>e.length>2)||n,r=a.length>90?a.slice(0,90)+"…":a,l=n.length>r.length||n.split("\n").length>1,c=document.createElement("div");c.style.cssText="display:grid;grid-template-columns:auto auto 1fr auto;align-items:center;gap:10px;padding:7px 10px;border-radius:6px;cursor:"+(l?"pointer":"default")+";transition:background .12s;border-bottom:1px solid var(--border);",c.onmouseenter=()=>{c.style.background="var(--bg-2)"},c.onmouseleave=()=>{c.style.background=""};const d=document.createElement("div");d.style.cssText="display:flex;align-items:center;gap:5px;white-space:nowrap;min-width:0;";const p=document.createElement("span");if(p.style.cssText="font-size:11px;font-weight:600;color:var(--text-1);max-width:110px;overflow:hidden;text-overflow:ellipsis;",p.textContent=(e.from||"?").replace("crew-",""),p.title=e.from||"",d.appendChild(p),e.to&&e.to!==e.from){const t=document.createElement("span");t.style.cssText="font-size:10px;color:var(--text-3);flex-shrink:0;",t.textContent="→";const n=document.createElement("span");n.style.cssText="font-size:11px;color:var(--text-2);max-width:110px;overflow:hidden;text-overflow:ellipsis;",n.textContent=(e.to||"").replace("crew-",""),n.title=e.to||"",d.appendChild(t),d.appendChild(n)}const m=document.createElement("div");m.style.cssText="display:flex;align-items:center;gap:4px;flex-shrink:0;";const u=document.createElement("span"),g=o||{color:"var(--text-3)",label:s.split(".").pop()||s};if(u.style.cssText="font-size:10px;font-weight:600;padding:2px 7px;border-radius:20px;white-space:nowrap;flex-shrink:0;color:#fff;background:"+g.color+";letter-spacing:.03em;",u.textContent=g.label,m.appendChild(u),"task.done"===s&&t.engineUsed){const e={claude:"#e07a5f",codex:"#8338ec",cursor:"#3d405b",opencode:"#06d6a0",gemini:"#4285f4","docker-sandbox":"#0db7ed"},n={claude:"🤖",codex:"🟣",cursor:"🖱",opencode:"⚡",gemini:"✨","docker-sandbox":"🐳"},s=t.engineUsed,o=document.createElement("span");o.style.cssText="font-size:10px;font-weight:600;padding:2px 6px;border-radius:20px;white-space:nowrap;flex-shrink:0;color:#fff;background:"+(e[s]||"var(--text-3)")+";",o.textContent=(n[s]||"")+" "+s,o.title="Executed by "+s,m.appendChild(o)}const x=document.createElement("span");x.style.cssText="font-size:12px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;",x.textContent=r;const f=document.createElement("div");f.style.cssText="display:flex;align-items:center;gap:6px;flex-shrink:0;";const y=document.createElement("span");if(y.style.cssText="font-size:10px;color:var(--text-3);white-space:nowrap;",y.textContent=i,f.appendChild(y),l){const e=document.createElement("span");e.style.cssText="font-size:10px;color:var(--text-3);",e.textContent="▸",f.appendChild(e)}if(c.appendChild(d),c.appendChild(m),c.appendChild(x),c.appendChild(f),l){const e=document.createElement("div");e.style.cssText="display:none;grid-column:1/-1;padding:8px 6px 4px;font-size:12px;color:var(--text-2);white-space:pre-wrap;word-break:break-word;max-height:300px;overflow-y:auto;border-top:1px solid var(--border);margin-top:4px;font-family:monospace;",e.textContent=n;const t=document.createElement("div");t.style.cssText="display:grid;grid-template-columns:1fr;border-radius:6px;overflow:hidden;border-bottom:1px solid var(--border);",c.style.borderBottom="none";let s=!1;return c.onclick=()=>{s=!s,e.style.display=s?"block":"none";const t=f.querySelector("span:last-child");t&&(t.textContent=s?"▾":"▸")},t.appendChild(c),t.appendChild(e),t}return c}(e)))}else{const e=document.createElement("div");e.style.cssText="padding:24px;text-align:center;font-size:12px;color:var(--text-3);",e.textContent="No events match the current filter.",c.appendChild(e)}if(e.replaceChildren(c),r)t.scrollTop=t.scrollHeight;else{const e=Math.max(0,t.scrollHeight-t.clientHeight);t.scrollTop=Math.min(l,e)}const d=document.getElementById("rtScrollBtn");d&&(d.style.display=a()?"none":"block"),t._scrollListenerBound||(t._scrollListenerBound=!0,t.addEventListener("scroll",()=>{d&&(d.style.display=a()?"none":"block")}))}function k(){y=!y;const e=document.getElementById("rtPauseBtn");e&&(e.textContent=y?"▶ Resume":"⏸ Pause",e.style.background=y?"var(--accent)":"",e.style.color=y?"#fff":"")}function T(){const e=document.getElementById("rtMessages");e&&(e.innerHTML='<div class="meta" style="padding:20px;text-align:center;opacity:.6;">Cleared. New messages will appear on next poll.</div>')}function I(){c(),document.getElementById("rtView").classList.add("active"),d("navRT"),function(){document.querySelectorAll(".rt-filter-chip").forEach(e=>{e.addEventListener("click",()=>{v=e.dataset.filter,document.querySelectorAll(".rt-filter-chip").forEach(t=>{const n=t===e;t.style.background=n?"var(--accent)":"transparent",t.style.color=n?"#fff":"var(--text-2)",t.classList.toggle("active",n)}),L()})});const e=document.getElementById("rtSearch");e&&e.addEventListener("input",()=>{h=e.value.trim(),L()})}(),L();const e=document.getElementById("rtScrollBtn");e&&(e.style.display="none")}async function B(){const e=document.getElementById("dlqMessages");e&&(e.innerHTML='<div style="padding:20px;">Loading…</div>');const t=await s("/api/dlq"),n=document.getElementById("dlqBadge");n&&(n.textContent=t.length,n.classList.toggle("hidden",!t.length)),e&&(e.innerHTML=t.length?t.map(e=>{const t=e.key||(e.filename||"").replace(".json","")||"?",n=o(t);return'<div class="msg dlq-item"><div class="meta"><strong>⚠️ Failed</strong> | '+(e.agent||"?")+" | "+(e.failedAt?new Date(e.failedAt).toLocaleString():"")+' <button class="replay-btn" data-action="replayDLQ" data-arg="'+n+'">Replay</button> <button data-action="deleteDLQ" data-arg="'+n+'" style="font-size:11px;padding:3px 8px;border-radius:4px;border:1px solid var(--red-hi);background:transparent;color:var(--red-hi);cursor:pointer;">Delete</button></div><div class="t">'+(e.error||"")+"</div></div>"}).join(""):'<div class="meta" style="padding:20px; text-align:center;">✓ DLQ empty</div>')}async function H(e){confirm("Replay?")&&(await l("/api/dlq/replay",{key:e}),r("Replayed"),B())}async function M(e){if(confirm("Delete this DLQ entry?"))try{await fetch("/api/dlq/"+encodeURIComponent(e),{method:"DELETE"}),r("DLQ entry deleted"),B()}catch(t){r("Failed: "+t.message,!0)}}function z(){c(),document.getElementById("dlqView").classList.add("active"),d("navDLQ"),B()}export{I as a,f as b,T as c,M as d,p as i,H as r,z as s,k as t};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as t,s as e,g as o,k as i,c as a}from"./core-utils-CAVnDoe1.js";const n={"grok-4-1-fast":[.2,.5],"grok-4-fast":[.2,.5],"grok-4":[3,15],"grok-3-mini":[.3,.5],"grok-3":[3,15],"grok-code-fast":[.2,1.5],"grok-beta":[5,15],"gpt-5.3-codex":[2.5,20],"gpt-5.2-codex":[1.75,14],"gpt-5.2":[1.75,14],"gpt-5.1-codex-max":[2.5,20],"gpt-5.1-codex-mini":[.25,2],"gpt-5.1-codex":[1.25,10],"gpt-5.1":[1.25,10],"gpt-5-codex":[1.25,10],"gpt-5-nano":[.15,.6],"gpt-5":[1.25,10],"codex-mini":[.25,2],"gpt-oss-120b":[.9,.9],"gpt-oss-20b":[.2,.2],"gpt-4o-mini":[.15,.6],"gpt-4o":[2.5,10],"gpt-4":[30,60],"deepseek-reasoner":[.7,2.5],"deepseek-chat":[.27,1.1],"mistral-large":[.5,1.5],"mistral-small":[.1,.3],"gemini-3.1-pro":[2.5,15],"gemini-3.1-flash":[.075,.3],"gemini-3-pro":[2.5,15],"gemini-3-flash":[.075,.3],"gemini-2.5-pro":[1.25,10],"gemini-2.5-flash-lite":[.04,.15],"gemini-2.5-flash":[.075,.3],"gemini-2.0-flash-lite":[.075,.3],"gemini-2.0-flash":[.1,.4],"claude-opus-4":[15,75],"claude-sonnet-4":[3,15],"claude-haiku-4":[.8,4],"claude-3-5-haiku":[.8,4],"claude-3-haiku":[.25,1.25],"claude-3-5-sonnet":[3,15],"claude-3-7-sonnet":[3,15],"kimi-k2-instruct":[1,3],"kimi-k2":[.6,2.5],"llama-4-maverick":[.5,.77],"llama-4-scout":[.11,.34],"llama-3.3-70b":[.59,.79],"llama-3.1-70b":[.59,.79],"llama3.1-70b":[.59,.79],"llama-3.1-8b":[.05,.08],"llama3.1-8b":[.1,.1],"qwen3-32b":[.29,.39],"llama-guard":[.2,.2],"sonar-pro":[3,15],sonar:[1,1],"big-pickle":[0,0],"trinity-large-preview":[0,0],"minimax-m2.5-free":[0,0],"glm-":[.1,.1],minimax:[.3,1],default:[1,3]};function s(t){let e=0;for(const[o,i]of Object.entries(t||{})){const t=Object.keys(n).find(t=>o.toLowerCase().includes(t))||"default",[a,s]=n[t];e+=i.prompt/1e6*a+i.completion/1e6*s}return e}async function r(){const t=document.getElementById("tokenUsageWidget");if(!t)return;const e=await o("/api/token-usage").catch(()=>({})),i=(e.prompt||0)+(e.completion||0),a=s(e.byModel);let r='<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:12px;"><div style="text-align:center;"><div style="font-size:20px;font-weight:700;color:var(--accent);">'+(e.calls||0).toLocaleString()+'</div><div style="font-size:11px;color:var(--text-3);margin-top:2px;">LLM calls</div></div><div style="text-align:center;"><div style="font-size:20px;font-weight:700;color:var(--green);">'+(i/1e3).toFixed(1)+'k</div><div style="font-size:11px;color:var(--text-3);margin-top:2px;">total tokens</div></div><div style="text-align:center;"><div style="font-size:20px;font-weight:700;color:var(--yellow);">$'+a.toFixed(4)+'</div><div style="font-size:11px;color:var(--text-3);margin-top:2px;">est. cost (all-time)</div></div></div>';const l=e.byDay||{},d=Object.keys(l).sort().reverse().slice(0,14);if(d.length){const t=Math.max(...d.map(function(t){return s(l[t].byModel||{})}),1e-4);r+='<div style="font-size:11px;font-weight:600;color:var(--text-2);margin:12px 0 6px;">Daily cost (last '+d.length+" days)</div>",r+='<div style="display:flex;flex-direction:column;gap:3px;">',d.forEach(function(e){const o=l[e],i=s(o.byModel||{}),a=Math.max(i/t*100,2),n=((o.prompt||0)+(o.completion||0))/1e3,d=e===(new Date).toISOString().slice(0,10);r+='<div style="display:flex;align-items:center;gap:8px;font-size:11px;"><span style="width:70px;color:var(--text-3);flex-shrink:0;">'+(d?"today":e.slice(5))+'</span><div style="flex:1;background:var(--bg-1);border-radius:3px;height:14px;overflow:hidden;"><div style="width:'+a.toFixed(1)+"%;height:100%;background:"+(d?"var(--accent)":"var(--green)")+';border-radius:3px;"></div></div><span style="width:52px;text-align:right;color:var(--yellow);font-weight:600;">$'+i.toFixed(4)+'</span><span style="width:44px;text-align:right;color:var(--text-3);">'+n.toFixed(1)+"k</span></div>"}),r+="</div>"}else r+='<div style="font-size:11px;color:var(--text-3);margin-top:8px;">No daily history yet — data accumulates with next LLM call after restart.</div>';Object.keys(e.byModel||{}).length&&(r+='<div style="font-size:11px;color:var(--text-3);margin:12px 0 6px;">By model (all-time)</div>',Object.entries(e.byModel||{}).sort((t,e)=>e[1].prompt+e[1].completion-(t[1].prompt+t[1].completion)).forEach(function(t){const e=t[0],o=t[1],i=Object.keys(n).find(function(t){return e.toLowerCase().includes(t)})||"default",a=n[i],s=o.prompt/1e6*a[0]+o.completion/1e6*a[1];r+='<div style="display:flex;justify-content:space-between;font-size:11px;padding:3px 0;border-bottom:1px solid var(--border);"><code style="color:var(--accent);">'+e+'</code><span style="color:var(--text-2);">'+((o.prompt+o.completion)/1e3).toFixed(1)+"k tok · $"+s.toFixed(4)+"</span></div>"})),t.innerHTML=r}async function l(e){var n;const s=document.getElementById("ocStatsWidget");if(!s)return;const r=(null==(n=document.getElementById("ocStatsDays"))?void 0:n.value)||"14";e&&e(null),i(s);try{const t=await o("/api/opencode-stats?days="+r);if(!t.ok||!Object.keys(t.byDay||{}).length)return void a(s,t.error||"No OpenCode data found");const i=t.byDay,n=Object.keys(i).sort().reverse(),l=n.reduce(function(t,e){return t+i[e].cost},0),d=n.reduce(function(t,e){return t+i[e].input_tok},0),c=n.reduce(function(t,e){return t+i[e].output_tok},0),p=n.reduce(function(t,e){return t+i[e].calls},0),g=Math.max(...n.map(function(t){return i[t].cost}),1e-4);let x='<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px;"><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--yellow);">$'+l.toFixed(4)+'</div><div style="font-size:11px;color:var(--text-3);">total cost</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--accent);">'+p.toLocaleString()+'</div><div style="font-size:11px;color:var(--text-3);">messages</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--green);">'+(d/1e6).toFixed(1)+'M</div><div style="font-size:11px;color:var(--text-3);">input tokens</div></div><div style="text-align:center;"><div style="font-size:18px;font-weight:700;color:var(--green);">'+(c/1e6).toFixed(2)+'M</div><div style="font-size:11px;color:var(--text-3);">output tokens</div></div></div>';x+='<div style="display:flex;flex-direction:column;gap:4px;margin-bottom:16px;">';const y=(new Date).toISOString().slice(0,10);n.forEach(function(t){const e=i[t],o=Math.max(e.cost/g*100,e.cost>0?2:0),a=t===y,n=(e.input_tok+e.output_tok)/1e6;x+='<div style="display:flex;align-items:center;gap:8px;font-size:11px;"><span style="width:70px;color:var(--text-3);flex-shrink:0;">'+(a?"today":t.slice(5))+'</span><div style="flex:1;background:var(--bg-1);border-radius:3px;height:16px;overflow:hidden;"><div style="width:'+o.toFixed(1)+"%;height:100%;background:"+(a?"var(--accent)":"var(--green)")+';border-radius:3px;opacity:0.85;"></div></div><span style="width:60px;text-align:right;color:var(--yellow);font-weight:600;">$'+e.cost.toFixed(4)+'</span><span style="width:50px;text-align:right;color:var(--text-3);">'+n.toFixed(2)+'M</span><span style="width:36px;text-align:right;color:var(--text-3);">'+e.calls+"</span></div>"}),x+="</div>";const v={};n.forEach(function(t){Object.entries(i[t].byModel||{}).forEach(function(t){const e=t[0],o=t[1];v[e]||(v[e]={cost:0,input_tok:0,output_tok:0,calls:0}),v[e].cost+=o.cost,v[e].input_tok+=o.input_tok,v[e].output_tok+=o.output_tok,v[e].calls+=o.calls})});const f=Object.entries(v).sort(function(t,e){return e[1].cost-t[1].cost});f.length&&(x+='<div style="font-size:11px;color:var(--text-3);margin-bottom:6px;">By model</div>',f.forEach(function(t){const e=t[0],o=t[1],i=(o.input_tok+o.output_tok)/1e6;x+='<div style="display:flex;justify-content:space-between;align-items:center;font-size:11px;padding:3px 0;border-bottom:1px solid var(--border);"><code style="color:var(--accent);">'+e+'</code><span style="color:var(--text-2);">'+i.toFixed(2)+"M tok · "+o.calls+' calls · <span style="color:var(--yellow);font-weight:600;">$'+o.cost.toFixed(4)+"</span></span></div>"})),e&&e(l),s.innerHTML=x}catch(l){t(s,"Error: "+l.message)}}async function d(){try{const t=await o("/api/crew-lead/status"),e=document.getElementById("crewLeadBadge");t.online?(e.textContent="● online",e.className="status-badge status-running"):(e.textContent="● offline",e.className="status-badge status-stopped")}catch{}}function c(t){const e=document.getElementById("taskLifecycleContainer");if(!e)return;if(!(t=t||[]).length)return void(e.innerHTML='<div class="card" style="padding:12px;"><div class="meta" style="font-size:12px;">Recent task lifecycle (dispatched → completed/failed/cancelled). Dispatch a task to see events.</div></div>');const o=t.slice().reverse().slice(0,15).map(t=>{const e=t.data||{},o=e.phase||"",i="completed"===o?"var(--green)":"failed"===o||"cancelled"===o?"var(--red)":"var(--accent)";return'<tr style="border-bottom:1px solid var(--border);"><td style="padding:6px 10px;font-size:11px;color:var(--text-3);">'+(t.occurredAt||"").replace("T"," ").slice(0,19)+'</td><td style="padding:6px 10px;font-size:12px;"><span style="color:'+i+';">'+o+'</span></td><td style="padding:6px 10px;font-size:12px;">'+(e.agentId||"")+'</td><td style="padding:6px 10px;font-size:11px;color:var(--text-3);">'+(e.taskId||"").slice(0,20)+"</td></tr>"}).join("");e.innerHTML='<div class="card" style="overflow:auto;"><div style="font-size:12px;font-weight:600;padding:8px 12px;border-bottom:1px solid var(--border);">Task lifecycle (schema 1.1)</div><table style="width:100%;border-collapse:collapse;font-size:12px;"><thead><tr style="border-bottom:1px solid var(--border);"><th style="text-align:left;padding:6px 10px;">Time</th><th style="text-align:left;padding:6px 10px;">Phase</th><th style="text-align:left;padding:6px 10px;">Agent</th><th style="text-align:left;padding:6px 10px;">Task ID</th></tr></thead><tbody>'+o+"</tbody></table></div>"}const p={read_file:"read",write_file:"write",mkdir:"mkdir",run_cmd:"run",dispatch:"dispatch",skill:"skill",define_skill:"define_skill",git:"git",telegram:"tg",whatsapp:"wa"};async function g(){const e=document.getElementById("toolMatrixContainer");if(e)try{const t=await fetch("/api/health"),o=await t.json().catch(()=>({}));if(!t.ok||!o.ok){const i=o.error||(401===t.status?"Unauthorized":t.statusText||"Request failed");return void(e.innerHTML='<div class="card" style="padding:16px;"><div style="color:var(--yellow);font-size:13px;font-weight:600;">Health check failed</div><div style="color:var(--text-2);font-size:12px;margin-top:8px;">'+(401===t.status?"RT token missing or invalid. Set it in Settings → System (RT token) or in ~/.crewswarm/crewswarm.json (rt.authToken).":i)+'</div><div style="color:var(--text-3);font-size:11px;margin-top:8px;">Ensure crew-lead is running on :5010 (Services tab).</div></div>')}window._telemetryEvents=o.telemetry||[],c(o.telemetry||[]);const i=(o.agents||[]).filter(t=>"crew-lead"!==(t.id||"").toLowerCase()),a=window._crewLeadInfo||{name:"Crew Lead",emoji:"🧠"},n=[{id:"crew-lead",name:a.name,emoji:a.emoji,tools:["read_file","write_file","mkdir","run_cmd","web_search","web_fetch","skill","define_skill","dispatch","telegram","whatsapp"]},...i],s=[...new Set(["define_skill","skill",...n.flatMap(t=>Array.isArray(t.tools)?t.tools:Object.keys(t.tools||{}))])].sort(),r=s.map(t=>p[t]||t);if(!n.length)return void(e.innerHTML='<div class="card" style="padding:16px;"><div style="color:var(--text-2);font-size:13px;">No agents in roster.</div><div style="color:var(--text-3);font-size:12px;margin-top:6px;">Add agents in Settings → Agents (or ~/.crewswarm/crewswarm.json), then start bridges from Services.</div></div>');let l='<div class="card" style="overflow:auto;"><table style="width:100%;border-collapse:collapse;font-size:12px;"><thead><tr style="border-bottom:1px solid var(--border);"><th style="text-align:left;padding:8px 12px;">Agent</th>';s.forEach((t,e)=>{l+='<th style="text-align:center;padding:8px 8px;" title="'+(t||"")+'">'+(r[e]||t)+"</th>"}),l+='<th style="text-align:right;padding:8px 12px;">Quick action</th></tr></thead><tbody>',n.forEach(t=>{const e=Array.isArray(t.tools)?t.tools:t.tools?Object.keys(t.tools).filter(e=>t.tools[e]):[],o=(t.emoji||"")+" "+(t.name||t.id||"");l+='<tr style="border-bottom:1px solid var(--border);">',l+='<td style="padding:8px 12px;"><strong>'+(o||t.id).replace(/</g,"<")+"</strong></td>",s.forEach(t=>{const o=e.includes(t);l+='<td style="text-align:center;padding:6px 8px;">'+(o?'<span style="color:var(--green);" title="'+t+'">✓</span>':'<span style="color:var(--text-3);">—</span>')+"</td>"}),l+='<td style="text-align:right;padding:8px 12px;"><button class="btn-ghost" style="font-size:11px;" data-action="restartAgentFromUI" data-arg="'+(t.id||"").replace(/"/g,""")+'">Restart</button></td></tr>'}),l+="</tbody></table></div>",e.innerHTML=l}catch(o){t(e,"Error loading health: "+(o.message||""))}}async function x(t){if(!t)return;const o=document.querySelector(`button[data-action="restartAgentFromUI"][data-arg="${t}"]`);o&&(o.disabled=!0,o.style.opacity="0.5",o.style.cursor="not-allowed");const i=Date.now(),a=window._lastAgentRestart||{};if(a[t]&&i-a[t]<3e3)return e("⏳ Restart already in progress...","warning"),void(o&&(o.disabled=!1,o.style.opacity="",o.style.cursor=""));window._lastAgentRestart||(window._lastAgentRestart={}),window._lastAgentRestart[t]=i;try{const i=await fetch("/api/agents/"+encodeURIComponent(t)+"/restart",{method:"POST",headers:{"Content-Type":"application/json"}}),a=await i.json();a.ok?(e("Restarting "+t+"…"),setTimeout(()=>{var t;if("usage"===(null==(t=window.appState)?void 0:t.activeTab)){const t=document.getElementById("healthAgentList");t&&null!==t.offsetParent&&window.loadAgentHealth&&window.loadAgentHealth()}},3e3)):(e(a.error||"Restart failed","error"),o&&(o.disabled=!1,o.style.opacity="",o.style.cursor=""))}catch(n){e(n.message||"Request failed","error"),o&&(o.disabled=!1,o.style.opacity="",o.style.cursor="")}}export{g as a,r as b,d as c,c as d,s as e,l,x as r};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(){const e=document.getElementById("waves-tab");if(!e)return;let t=null;async function n(){try{const e=await fetch("/api/waves/config");t=await e.json(),a()}catch(e){d("Failed to load waves config: "+e.message)}}function a(){if(!t)return;const n=`\n <div class="waves-header" style="margin-bottom: 24px;">\n <h2 style="margin: 0 0 8px 0;">Planning Pipeline Waves</h2>\n <p style="margin: 0; color: var(--text-2); font-size: 14px;">\n Configure the 3-wave planning pipeline that runs when you say "build me X"\n </p>\n </div>\n\n <div class="wave-templates" style="margin-bottom: 32px;">\n <div style="font-weight: 600; margin-bottom: 12px;">Templates:</div>\n <div style="display: flex; gap: 12px; flex-wrap: wrap;">\n ${Object.entries(t.templates||{}).map(([e,t])=>`\n <button class="template-btn" data-template="${e}" style="padding: 12px 16px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-2); cursor: pointer;">\n <div style="font-weight: 600; margin-bottom: 4px;">${t.name}</div>\n <div style="font-size: 12px; color: var(--text-3);">${t.description}</div>\n </button>\n `).join("")}\n </div>\n </div>\n\n <div class="waves-list">\n ${t.waves.map(e=>function(e){return`\n <div class="wave-card" data-wave-id="${e.id}" style="margin-bottom: 24px; padding: 20px; background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px;">\n <div class="wave-header" style="margin-bottom: 16px;">\n <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 8px;">\n <div style="font-size: 20px; font-weight: 700;">Wave ${e.id}</div>\n <div style="font-size: 14px; font-weight: 600; color: var(--text-1);">${e.name}</div>\n </div>\n <div style="font-size: 13px; color: var(--text-3);">${e.description}</div>\n </div>\n\n <div class="wave-agents" style="display: flex; flex-direction: column; gap: 12px;">\n ${e.agents.map((t,n)=>function(e,t,n){return`\n <div class="agent-slot" data-wave-id="${e}" data-agent-idx="${n}" style="padding: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 8px;">\n <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 8px;">\n <select class="agent-select" data-wave-id="${e}" data-agent-idx="${n}" style="padding: 6px 12px; border-radius: 6px; border: 1px solid var(--border); background: var(--surface-2); font-size: 13px; font-weight: 600;">\n <option value="${t.id}" selected>${t.id}</option>\n <option value="crew-researcher">crew-researcher</option>\n <option value="crew-copywriter">crew-copywriter</option>\n <option value="crew-pm">crew-pm</option>\n <option value="crew-architect">crew-architect</option>\n <option value="crew-coder-front">crew-coder-front</option>\n <option value="crew-frontend">crew-frontend</option>\n <option value="crew-qa">crew-qa</option>\n <option value="crew-security">crew-security</option>\n <option value="crew-main">crew-main</option>\n </select>\n <button class="remove-agent-btn" data-wave-id="${e}" data-agent-idx="${n}" style="padding: 6px 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-size: 12px; color: var(--text-3);">\n ✕ Remove\n </button>\n </div>\n <textarea class="agent-task" data-wave-id="${e}" data-agent-idx="${n}" rows="3" style="width: 100%; padding: 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--surface-2); font-size: 12px; font-family: 'SF Mono', monospace; resize: vertical;">${t.task}</textarea>\n </div>\n `}(e.id,t,n)).join("")}\n </div>\n\n <button class="add-agent-btn" data-wave-id="${e.id}" style="margin-top: 12px; padding: 8px 16px; background: var(--surface-2); border: 1px dashed var(--border); border-radius: 6px; cursor: pointer; font-size: 13px; color: var(--text-2);">\n + Add Agent to Wave ${e.id}\n </button>\n </div>\n `}(e)).join("")}\n </div>\n\n <div style="margin-top: 24px; display: flex; gap: 12px;">\n <button id="saveWavesBtn" style="padding: 12px 24px; background: var(--accent); color: white; border: none; border-radius: 8px; font-weight: 600; cursor: pointer;">\n 💾 Save Configuration\n </button>\n <button id="resetWavesBtn" style="padding: 12px 24px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; font-weight: 600; cursor: pointer;">\n ↺ Reset to Default\n </button>\n </div>\n `;var d,s;e.innerHTML=n,document.querySelectorAll(".agent-select").forEach(e=>{e.addEventListener("change",e=>{const n=parseInt(e.target.dataset.waveId),a=parseInt(e.target.dataset.agentIdx),r=t.waves.find(e=>e.id===n);r&&r.agents[a]&&(r.agents[a].id=e.target.value)})}),document.querySelectorAll(".agent-task").forEach(e=>{e.addEventListener("change",e=>{const n=parseInt(e.target.dataset.waveId),a=parseInt(e.target.dataset.agentIdx),r=t.waves.find(e=>e.id===n);r&&r.agents[a]&&(r.agents[a].task=e.target.value)})}),document.querySelectorAll(".remove-agent-btn").forEach(e=>{e.addEventListener("click",e=>{const n=parseInt(e.target.dataset.waveId),r=parseInt(e.target.dataset.agentIdx),o=t.waves.find(e=>e.id===n);o&&(o.agents.splice(r,1),a())})}),document.querySelectorAll(".add-agent-btn").forEach(e=>{e.addEventListener("click",e=>{const n=parseInt(e.target.dataset.waveId),r=t.waves.find(e=>e.id===n);r&&(r.agents.push({id:"crew-main",task:"[TASK] Describe what this agent should do..."}),a())})}),document.querySelectorAll(".template-btn").forEach(e=>{e.addEventListener("click",e=>{!function(e){const n=t.templates[e];n&&(n.wave_overrides&&Object.entries(n.wave_overrides).forEach(([e,n])=>{const a=parseInt(e),r=t.waves.find(e=>e.id===a);r&&n.agents&&(r.agents=n.agents)}),a(),i(`Applied template: ${n.name}`))}(e.target.closest(".template-btn").dataset.template)})}),null==(d=document.getElementById("saveWavesBtn"))||d.addEventListener("click",r),null==(s=document.getElementById("resetWavesBtn"))||s.addEventListener("click",o)}async function r(){try{const e=await fetch("/api/waves/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(await e.text());i("Waves configuration saved")}catch(e){d("Failed to save: "+e.message)}}async function o(){if(confirm("Reset waves to default configuration?"))try{const e=await fetch("/api/waves/config/reset",{method:"POST"});if(!e.ok)throw new Error(await e.text());await n(),i("Reset to default configuration")}catch(e){d("Failed to reset: "+e.message)}}function i(e){const t=document.createElement("div");t.textContent="✅ "+e,t.style.cssText="position: fixed; top: 20px; right: 20px; background: var(--success); color: white; padding: 12px 20px; border-radius: 8px; z-index: 10000; font-weight: 600;",document.body.appendChild(t),setTimeout(()=>t.remove(),3e3)}function d(e){const t=document.createElement("div");t.textContent="❌ "+e,t.style.cssText="position: fixed; top: 20px; right: 20px; background: var(--error); color: white; padding: 12px 20px; border-radius: 8px; z-index: 10000; font-weight: 600;",document.body.appendChild(t),setTimeout(()=>t.remove(),5e3)}n()}export{e as i};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as e,e as t,s as n,p as o}from"./core-utils-CAVnDoe1.js";let a=()=>{},l=()=>{},s=[],i=[];const d={selectedName:"",list:[],runStatus:{},editorWorkflow:null},r=[{id:"daily-research",name:"Daily Research Brief",description:"Research, summarize, then QA-check every weekday morning.",schedule:"0 9 * * 1-5",stages:[{agent:"crew-researcher",task:"Research top 5 updates for our current project and summarize key signals."},{agent:"crew-pm",task:"Turn the research into a concise daily brief with priorities and risks."},{agent:"crew-qa",task:"Review the brief for factual clarity and missing edge cases."}]},{id:"seo-content",name:"SEO Content Pipeline",description:"Generate SEO topic ideas, draft copy, then edit.",schedule:"30 10 * * 1,3,5",stages:[{agent:"crew-seo",task:"Find one high-intent keyword cluster and propose a short content outline."},{agent:"crew-copywriter",task:"Write a first draft from the outline. Keep it scannable and conversion-focused."},{agent:"crew-main",task:"Polish the draft and produce final publish-ready copy."}]},{id:"code-health",name:"Code Health Sweep",description:"Automated PM->Coder->QA quality pass.",schedule:"0 14 * * 1-5",stages:[{agent:"crew-pm",task:"Pick one high-value backlog item from project context and define acceptance criteria."},{agent:"crew-coder",task:"Implement the scoped item in small safe changes and summarize files touched."},{agent:"crew-qa",task:"Audit the changes, run tests, and report any regressions with severity."}]}];function c(e=""){return{name:e,description:"",enabled:!1,schedule:"",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,stages:[{agent:"crew-main",task:"",tool:""}]}}function p(e={}){a=e.hideAllViews||a,l=e.setNavActive||l}async function m(){var t;a(),null==(t=document.getElementById("workflowsView"))||t.classList.add("active"),l("navWorkflows"),await async function(){try{const t=await e("/api/agents");s=(t||[]).map(e=>"string"==typeof e?e:e.id||e.agent).filter(Boolean).sort()}catch{s=[]}}(),await async function(){try{const t=await e("/api/skills");i=(t.skills||[]).map(e=>({name:e.name||"",description:e.description||"",type:e.type||(e.url?"api":"knowledge")})).filter(e=>e.name).sort((e,t)=>e.name.localeCompare(t.name))}catch{i=[]}}(),await f()}async function f(){const n=document.getElementById("workflowList");if(n){n.innerHTML='<div class="meta" style="padding:10px;">Loading workflows...</div>';try{const t=await e("/api/workflows/list");d.list=t.workflows||[],u(),d.selectedName?await w(d.selectedName):y(c());const n=t.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone,o=document.getElementById("workflowTimezoneLabel");o&&(o.textContent=`Local timezone: ${n}`)}catch(o){n.innerHTML=`<div class="meta" style="padding:10px;color:var(--red-hi);">Failed to load workflows: ${t(o.message)}</div>`}}}function u(){const e=document.getElementById("workflowList");if(!e)return;const n=d.list||[];n.length?(e.innerHTML=n.map(e=>{var n;const o=e.name===d.selectedName?"background:var(--bg-2);border-color:var(--accent);":"",a=e.schedule?t(e.schedule):'<span style="opacity:0.7;">no schedule</span>',l=(null==(n=e.runState)?void 0:n.running)?'<span style="color:var(--green-hi);font-size:11px;">running</span>':"";return`\n <button class="btn-ghost workflow-row" data-workflow-name="${t(e.name)}" style="width:100%;text-align:left;display:flex;flex-direction:column;gap:4px;padding:10px;margin-bottom:8px;${o}">\n <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">\n <strong style="font-size:13px;">${t(e.name)}</strong>\n ${l}\n </div>\n <div style="font-size:11px;color:var(--text-3);">${e.enabled?"enabled":"disabled"} · ${e.stageCount||0} stage(s)</div>\n <div style="font-size:11px;color:var(--text-2);font-family:monospace;">${a}</div>\n </button>\n `}).join(""),e.querySelectorAll(".workflow-row").forEach(e=>{e.addEventListener("click",async()=>{const t=e.dataset.workflowName||"";await w(t)})})):e.innerHTML='<div class="meta" style="padding:10px;">No workflows yet.</div>'}async function w(t){if(t)try{const n=await e(`/api/workflows/item?name=${encodeURIComponent(t)}`);d.selectedName=t,d.runStatus=n.runState||{},u(),y({name:t,...n.workflow||{}},n),await async function(t){const n=document.getElementById("workflowLog");if(!n||!t)return;try{const o=(await e(`/api/workflows/log?name=${encodeURIComponent(t)}&limit=120`)).lines||[];n.textContent=o.length?o.join("\n"):"No log lines yet.",n.scrollTop=n.scrollHeight}catch(o){n.textContent=`Failed to load log: ${o.message}`}}(t)}catch(o){n(`Failed to load workflow: ${o.message}`,"error")}}function g(e){const t=String(e||"").trim();if(!t)return"No schedule set. Add a cron expression or use a preset.";return{"*/15 * * * *":"Runs every 15 minutes","0 * * * *":"Runs hourly at minute 0","0 9 * * 1-5":"Runs weekdays at 9:00","0 9 * * *":"Runs daily at 9:00","0 0 * * 1":"Runs every Monday at midnight","0 8 1 * *":"Runs monthly on day 1 at 8:00"}[t]||"Custom cron schedule"}function y(e,o={}){const a=document.getElementById("workflowEditor");if(!a)return;const l={...c(),...e},p=Array.isArray(l.stages)&&l.stages.length?l.stages:c().stages;d.editorWorkflow={...l,stages:p.map(e=>({...e}))};const m=o.cronExample?t(o.cronExample):`*/15 * * * * cd ${t(window.location.pathname||".")} && node scripts/run-scheduled-pipeline.mjs ${t(l.name||"my-workflow")}`,u={agents:s.length?s.map(e=>`<code style="font-size:11px;">${t(e)}</code>`).join(" "):'<span style="font-size:11px;color:var(--text-3);">No agents loaded</span>',skills:i.length?i.map(e=>`<div style="font-size:11px;line-height:1.4;"><code>${t(e.name)}</code> <span style="color:var(--text-3);">(${t(e.type)})</span></div>`).join(""):'<span style="font-size:11px;color:var(--text-3);">No skills loaded</span>'};a.innerHTML=`\n <div class="card" style="display:flex;flex-direction:column;gap:12px;">\n <div style="display:flex;gap:8px;flex-wrap:wrap;">\n <button id="wfOpenTemplateLibraryBtn" class="btn-ghost" style="font-size:12px;">📚 Job Library</button>\n <button id="wfOpenSkillGuideBtn" class="btn-ghost" style="font-size:12px;">🧩 Skills & Agent Options</button>\n <button id="wfOpenJsonEditorBtn" class="btn-ghost" style="font-size:12px;">{ } Advanced JSON</button>\n </div>\n\n <div style="display:flex;gap:10px;flex-wrap:wrap;">\n <div style="flex:1;min-width:260px;">\n <label style="font-size:12px;font-weight:600;">Name</label>\n <input id="wfName" type="text" value="${t(l.name||"")}" placeholder="daily-research" style="width:100%;margin-top:4px;padding:8px 10px;" />\n </div>\n <div style="flex:1;min-width:260px;">\n <label style="font-size:12px;font-weight:600;">Description</label>\n <input id="wfDescription" type="text" value="${t(l.description||"")}" placeholder="What this workflow does" style="width:100%;margin-top:4px;padding:8px 10px;" />\n </div>\n </div>\n\n <div style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;">\n <div style="min-width:280px;flex:1;">\n <label style="font-size:12px;font-weight:600;">Cron Schedule</label>\n <input id="wfSchedule" type="text" value="${t(l.schedule||"")}" placeholder="0 9 * * 1-5" style="width:100%;margin-top:4px;padding:8px 10px;font-family:monospace;" />\n <div style="font-size:11px;color:var(--text-3);margin-top:4px;">Format: minute hour day month weekday</div>\n <div style="display:flex;gap:6px;flex-wrap:wrap;margin-top:8px;">${[{label:"Every 15m",cron:"*/15 * * * *"},{label:"Hourly",cron:"0 * * * *"},{label:"Daily 9am",cron:"0 9 * * *"},{label:"Weekdays 9am",cron:"0 9 * * 1-5"},{label:"Weekly Mon",cron:"0 0 * * 1"},{label:"Monthly",cron:"0 8 1 * *"}].map(e=>`<button class="btn-ghost wf-cron-preset" data-cron="${t(e.cron)}" style="font-size:11px;padding:4px 8px;">${t(e.label)}</button>`).join("")}</div>\n <div id="wfScheduleHint" style="font-size:11px;color:var(--text-2);margin-top:6px;">${t(g(l.schedule))}</div>\n </div>\n <label style="display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;padding-bottom:8px;">\n <input id="wfEnabled" type="checkbox" ${l.enabled?"checked":""} />\n Enabled\n </label>\n </div>\n\n <div id="workflowTimezoneLabel" style="font-size:11px;color:var(--text-3);"></div>\n\n <div>\n <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">\n <label style="font-size:12px;font-weight:600;">Stages (wave-like, runs top to bottom)</label>\n <button id="wfAddStageBtn" class="btn-ghost" style="font-size:12px;">+ Add Stage</button>\n </div>\n <div id="wfStagesWrap" style="display:flex;flex-direction:column;gap:8px;">\n ${p.map((e,n)=>{return`\n <div class="wf-stage-row" data-stage-index="${n}" style="border:1px solid var(--border);border-radius:8px;padding:10px;background:var(--bg-2);">\n <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px;">\n <strong style="font-size:12px;">Stage ${n+1}</strong>\n <div style="display:flex;gap:6px;flex-wrap:wrap;">\n <button class="btn-ghost wf-move-stage-up" data-stage-index="${n}" style="font-size:11px;padding:4px 8px;">↑</button>\n <button class="btn-ghost wf-move-stage-down" data-stage-index="${n}" style="font-size:11px;padding:4px 8px;">↓</button>\n <button class="btn-ghost wf-duplicate-stage" data-stage-index="${n}" style="font-size:11px;padding:4px 8px;">Duplicate</button>\n <button class="btn-red wf-remove-stage" data-stage-index="${n}" style="font-size:11px;padding:4px 8px;">Remove</button>\n </div>\n </div>\n <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:8px;">\n <div style="flex:1;min-width:220px;">\n <label style="font-size:11px;font-weight:600;">Agent</label>\n <select class="wf-agent" style="width:100%;margin-top:4px;padding:6px 8px;">${o=e.agent,Array.from(new Set([...s||[],"crew-main","crew-pm","crew-qa","crew-coder","crew-coder-front","crew-coder-back","crew-copywriter",o||""])).filter(Boolean).sort().map(e=>`<option value="${t(e)}" ${e===o?"selected":""}>${t(e)}</option>`).join("")}</select>\n </div>\n <div style="width:180px;">\n <label style="font-size:11px;font-weight:600;">Tool hint (optional)</label>\n <input class="wf-tool" type="text" value="${t(e.tool||"")}" placeholder="write_file" style="width:100%;margin-top:4px;padding:6px 8px;" />\n </div>\n </div>\n <div>\n <label style="font-size:11px;font-weight:600;">Task</label>\n <textarea class="wf-task" rows="3" style="width:100%;margin-top:4px;padding:8px 10px;font-family:monospace;">${t(e.task||"")}</textarea>\n </div>\n </div>\n `;var o}).join("")}\n </div>\n </div>\n\n <div style="display:flex;gap:8px;flex-wrap:wrap;">\n <button id="wfSaveBtn" class="btn">Save Workflow</button>\n <button id="wfRunBtn" class="btn-green">Run Now</button>\n <button id="wfDeleteBtn" class="btn-red">Delete</button>\n <button id="wfNewBtn" class="btn-ghost">New</button>\n <button id="wfRefreshBtn" class="btn-ghost">Refresh</button>\n </div>\n\n <div>\n <div style="font-size:11px;font-weight:600;color:var(--text-2);margin-bottom:4px;">Crontab example</div>\n <code style="display:block;background:var(--bg-2);border:1px solid var(--border);padding:8px 10px;border-radius:6px;overflow:auto;white-space:nowrap;">${m}</code>\n </div>\n\n <div id="wfLibraryModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.55);z-index:12000;align-items:center;justify-content:center;padding:18px;">\n <div style="width:min(960px,100%);max-height:85vh;overflow:auto;background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:14px;">\n <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;">\n <div style="font-size:14px;font-weight:700;">Workflow Job Library</div>\n <button id="wfCloseLibraryBtn" class="btn-ghost" style="font-size:12px;">Close</button>\n </div>\n <div style="font-size:12px;color:var(--text-2);margin-bottom:10px;">Pick a starter template, then customize stages/tasks.</div>\n <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px;">${r.map(e=>`\n <div style="border:1px solid var(--border);border-radius:8px;padding:10px;background:var(--bg-2);">\n <div style="font-size:12px;font-weight:700;">${t(e.name)}</div>\n <div style="font-size:11px;color:var(--text-3);margin-top:4px;">${t(e.description)}</div>\n <div style="font-size:11px;color:var(--text-2);font-family:monospace;margin-top:6px;">${t(e.schedule)}</div>\n <div style="margin-top:8px;">\n <button class="btn-ghost wf-apply-template" data-template-id="${t(e.id)}" style="font-size:11px;">Use Template</button>\n </div>\n </div>\n `).join("")}</div>\n <hr style="border:none;border-top:1px solid var(--border);margin:14px 0;" />\n <div style="font-size:12px;font-weight:700;margin-bottom:6px;">Available Agents</div>\n <div style="display:flex;gap:6px;flex-wrap:wrap;">${u.agents}</div>\n <div style="font-size:12px;font-weight:700;margin:12px 0 6px;">Available Skills</div>\n <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:6px;">${u.skills}</div>\n </div>\n </div>\n\n <div id="wfJsonModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.55);z-index:12000;align-items:center;justify-content:center;padding:18px;">\n <div style="width:min(920px,100%);max-height:85vh;overflow:auto;background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:14px;">\n <div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;">\n <div style="font-size:14px;font-weight:700;">Advanced Workflow JSON</div>\n <button id="wfCloseJsonBtn" class="btn-ghost" style="font-size:12px;">Close</button>\n </div>\n <div style="font-size:12px;color:var(--text-2);margin-bottom:8px;">Edit raw JSON. Supports both <code>stages</code> and <code>steps</code>.</div>\n <textarea id="wfJsonTextarea" rows="18" style="width:100%;font-family:monospace;font-size:12px;padding:10px;border:1px solid var(--border);border-radius:8px;background:var(--bg-2);"></textarea>\n <div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap;">\n <button id="wfApplyJsonBtn" class="btn-green">Apply JSON</button>\n </div>\n </div>\n </div>\n </div>\n `;const w=document.getElementById("workflowTimezoneLabel");var k,E,B,I,z,S,$,L,A,N,D,T,J,C,O;w&&(w.textContent=`Local timezone: ${Intl.DateTimeFormat().resolvedOptions().timeZone}`),null==(k=document.getElementById("wfOpenTemplateLibraryBtn"))||k.addEventListener("click",e=>{e.preventDefault();const t=document.getElementById("wfLibraryModal");t&&(t.style.display="flex")}),null==(E=document.getElementById("wfOpenSkillGuideBtn"))||E.addEventListener("click",e=>{e.preventDefault();const t=document.getElementById("wfLibraryModal");t&&(t.style.display="flex")}),null==(B=document.getElementById("wfCloseLibraryBtn"))||B.addEventListener("click",e=>{e.preventDefault();const t=document.getElementById("wfLibraryModal");t&&(t.style.display="none")}),null==(I=document.getElementById("wfLibraryModal"))||I.addEventListener("click",e=>{var t;"wfLibraryModal"===(null==(t=e.target)?void 0:t.id)&&(e.currentTarget.style.display="none")}),null==(z=document.getElementById("wfOpenJsonEditorBtn"))||z.addEventListener("click",e=>{var t;e.preventDefault();const n={...v().workflow,...(null==(t=d.editorWorkflow)?void 0:t.steps)?{steps:d.editorWorkflow.steps}:{}},o=document.getElementById("wfJsonTextarea");o&&(o.value=JSON.stringify(n,null,2));const a=document.getElementById("wfJsonModal");a&&(a.style.display="flex")}),null==(S=document.getElementById("wfCloseJsonBtn"))||S.addEventListener("click",e=>{e.preventDefault();const t=document.getElementById("wfJsonModal");t&&(t.style.display="none")}),null==($=document.getElementById("wfJsonModal"))||$.addEventListener("click",e=>{var t;"wfJsonModal"===(null==(t=e.target)?void 0:t.id)&&(e.currentTarget.style.display="none")}),null==(L=document.getElementById("wfApplyJsonBtn"))||L.addEventListener("click",e=>{e.preventDefault();try{const e=document.getElementById("wfJsonTextarea"),t=JSON.parse((null==e?void 0:e.value)||"{}"),o=v();y({name:o.name,description:t.description||o.workflow.description,enabled:t.enabled??o.workflow.enabled,schedule:t.schedule||o.workflow.schedule,timezone:t.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone,stages:Array.isArray(t.stages)&&t.stages.length?t.stages:o.workflow.stages,...Array.isArray(t.steps)?{steps:t.steps}:{}});const a=document.getElementById("wfJsonModal");a&&(a.style.display="none"),n("Applied advanced JSON","success")}catch(t){n(`Invalid JSON: ${t.message}`,"error")}}),document.querySelectorAll(".wf-apply-template").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const o=e.dataset.templateId||"",a=r.find(e=>e.id===o);if(!a)return;const l=v();y({name:l.name||a.id,description:a.description,enabled:l.workflow.enabled,schedule:a.schedule,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,stages:a.stages.map(e=>({...e,tool:e.tool||""}))});const s=document.getElementById("wfLibraryModal");s&&(s.style.display="none"),n(`Applied template: ${a.name}`,"success")})}),document.querySelectorAll(".wf-cron-preset").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const n=e.dataset.cron||"",o=document.getElementById("wfSchedule"),a=document.getElementById("wfScheduleHint");o&&(o.value=n),a&&(a.textContent=g(n))})}),null==(A=document.getElementById("wfSchedule"))||A.addEventListener("input",e=>{const t=document.getElementById("wfScheduleHint");t&&(t.textContent=g(e.target.value))}),null==(N=document.getElementById("wfAddStageBtn"))||N.addEventListener("click",e=>{e.preventDefault();const t=v({includeIncompleteStages:!0});t.workflow.stages.push({agent:"crew-main",task:"",tool:""}),y({name:t.name,...t.workflow})}),document.querySelectorAll(".wf-remove-stage").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const n=Number(e.dataset.stageIndex||"-1"),o=v({includeIncompleteStages:!0});o.workflow.stages=o.workflow.stages.filter((e,t)=>t!==n),o.workflow.stages.length||(o.workflow.stages=[{agent:"crew-main",task:"",tool:""}]),y({name:o.name,...o.workflow})})}),document.querySelectorAll(".wf-move-stage-up").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const n=Number(e.dataset.stageIndex||"-1");if(n<=0)return;const o=v({includeIncompleteStages:!0}),[a]=o.workflow.stages.splice(n,1);o.workflow.stages.splice(n-1,0,a),y({name:o.name,...o.workflow})})}),document.querySelectorAll(".wf-move-stage-down").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const n=Number(e.dataset.stageIndex||"-1"),o=v({includeIncompleteStages:!0});if(n<0||n>=o.workflow.stages.length-1)return;const[a]=o.workflow.stages.splice(n,1);o.workflow.stages.splice(n+1,0,a),y({name:o.name,...o.workflow})})}),document.querySelectorAll(".wf-duplicate-stage").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const n=Number(e.dataset.stageIndex||"-1"),o=v({includeIncompleteStages:!0});if(n<0||n>=o.workflow.stages.length)return;const a=o.workflow.stages[n];o.workflow.stages.splice(n+1,0,{...a}),y({name:o.name,...o.workflow})})}),null==(D=document.getElementById("wfSaveBtn"))||D.addEventListener("click",x),null==(T=document.getElementById("wfRunBtn"))||T.addEventListener("click",b),null==(J=document.getElementById("wfDeleteBtn"))||J.addEventListener("click",h),null==(C=document.getElementById("wfNewBtn"))||C.addEventListener("click",()=>{d.selectedName="",y(c());const e=document.getElementById("workflowLog");e&&(e.textContent="")}),null==(O=document.getElementById("wfRefreshBtn"))||O.addEventListener("click",async()=>{await f()})}function v(e={}){var t,n,o,a,l;const{includeIncompleteStages:s=!1}=e,i=((null==(t=document.getElementById("wfName"))?void 0:t.value)||"").trim(),r=((null==(n=document.getElementById("wfDescription"))?void 0:n.value)||"").trim(),c=((null==(o=document.getElementById("wfSchedule"))?void 0:o.value)||"").trim(),p=!!(null==(a=document.getElementById("wfEnabled"))?void 0:a.checked),m=Array.from(document.querySelectorAll(".wf-stage-row")).map(e=>{var t,n,o,a,l,s;const i=(null==(n=null==(t=e.querySelector(".wf-agent"))?void 0:t.value)?void 0:n.trim())||"",d=(null==(a=null==(o=e.querySelector(".wf-tool"))?void 0:o.value)?void 0:a.trim())||"";return{agent:i,task:(null==(s=null==(l=e.querySelector(".wf-task"))?void 0:l.value)?void 0:s.trim())||"",...d?{tool:d}:{}}}).filter(e=>s||e.agent&&e.task),f=Array.isArray(null==(l=d.editorWorkflow)?void 0:l.steps)?d.editorWorkflow.steps:[];return{name:i,workflow:{description:r,enabled:p,schedule:c,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,stages:m,...f.length?{steps:f}:{}}}}async function x(){const e=v();if(e.name)if(e.workflow.stages.length)try{await o("/api/workflows/save",e),d.selectedName=e.name,n(`Saved workflow: ${e.name}`,"success"),await f(),await w(e.name)}catch(t){n(`Save failed: ${t.message}`,"error")}else n("Add at least one stage","error");else n("Workflow name is required","error")}async function b(){const e=v();if(e.name)try{const t=await o("/api/workflows/run",{name:e.name});n(`Started ${e.name}${t.pid?` (pid ${t.pid})`:""}`,"success"),await w(e.name)}catch(t){n(`Run failed: ${t.message}`,"error")}else n("Save workflow first (name required)","warning")}async function h(){const e=v();if(e.name){if(confirm(`Delete workflow "${e.name}"?`))try{await o("/api/workflows/delete",{name:e.name}),n(`Deleted ${e.name}`,"success"),d.selectedName="",await f(),y(c());const t=document.getElementById("workflowLog");t&&(t.textContent="")}catch(t){n(`Delete failed: ${t.message}`,"error")}}else n("No workflow selected","warning")}export{p as i,m as s};
|
|
Binary file
|
|
Binary file
|