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,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized error handlers and response helpers for Dashboard API
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// ── Response Helpers ──────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Send a successful JSON response
|
|
9
|
+
*/
|
|
10
|
+
export function jsonOk(res, data = {}) {
|
|
11
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
12
|
+
res.end(JSON.stringify({ ok: true, ...data }));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Send an error JSON response with appropriate HTTP status
|
|
17
|
+
*/
|
|
18
|
+
export function jsonError(res, status, message, details = null) {
|
|
19
|
+
res.writeHead(status, { 'content-type': 'application/json' });
|
|
20
|
+
const payload = { ok: false, error: message };
|
|
21
|
+
if (details) payload.details = details;
|
|
22
|
+
res.end(JSON.stringify(payload));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Send a validation error (400)
|
|
27
|
+
*/
|
|
28
|
+
export function validationError(res, message, details = null) {
|
|
29
|
+
jsonError(res, 400, message, details);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Send a not found error (404)
|
|
34
|
+
*/
|
|
35
|
+
export function notFoundError(res, message = 'Resource not found') {
|
|
36
|
+
jsonError(res, 404, message);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Send an internal server error (500)
|
|
41
|
+
*/
|
|
42
|
+
export function serverError(res, message = 'Internal server error', details = null) {
|
|
43
|
+
jsonError(res, 500, message, details);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ── Request Helpers ───────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parse JSON body from request with error handling
|
|
50
|
+
*/
|
|
51
|
+
export async function parseJsonBody(req) {
|
|
52
|
+
let body = '';
|
|
53
|
+
for await (const chunk of req) body += chunk;
|
|
54
|
+
|
|
55
|
+
if (!body.trim()) {
|
|
56
|
+
return { ok: false, error: 'Empty request body' };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(body);
|
|
61
|
+
return { ok: true, data: parsed };
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return { ok: false, error: 'Invalid JSON: ' + err.message };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── Process Helpers ───────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Spawn a child process with better error handling and timeout
|
|
71
|
+
* Replaces execSync for safer command execution
|
|
72
|
+
*/
|
|
73
|
+
export async function spawnAsync(command, args = [], options = {}) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
import('node:child_process').then(({ spawn }) => {
|
|
76
|
+
const timeout = options.timeout || 10000;
|
|
77
|
+
const encoding = options.encoding || 'utf8';
|
|
78
|
+
|
|
79
|
+
const proc = spawn(command, args, {
|
|
80
|
+
...options,
|
|
81
|
+
timeout: undefined, // We'll handle timeout manually
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
let stdout = '';
|
|
85
|
+
let stderr = '';
|
|
86
|
+
let timedOut = false;
|
|
87
|
+
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
timedOut = true;
|
|
90
|
+
proc.kill('SIGTERM');
|
|
91
|
+
setTimeout(() => proc.kill('SIGKILL'), 1000); // Force kill after 1s
|
|
92
|
+
}, timeout);
|
|
93
|
+
|
|
94
|
+
if (proc.stdout) {
|
|
95
|
+
proc.stdout.on('data', (data) => {
|
|
96
|
+
stdout += data.toString(encoding);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (proc.stderr) {
|
|
101
|
+
proc.stderr.on('data', (data) => {
|
|
102
|
+
stderr += data.toString(encoding);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
proc.on('error', (err) => {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
reject(new Error(`Failed to spawn ${command}: ${err.message}`));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
proc.on('close', (code) => {
|
|
112
|
+
clearTimeout(timer);
|
|
113
|
+
|
|
114
|
+
if (timedOut) {
|
|
115
|
+
reject(new Error(`Command timed out after ${timeout}ms: ${command} ${args.join(' ')}`));
|
|
116
|
+
} else if (code === 0) {
|
|
117
|
+
resolve({ stdout, stderr, code });
|
|
118
|
+
} else {
|
|
119
|
+
reject(new Error(`Command exited with code ${code}: ${stderr || stdout}`));
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Check if a process is running by pattern
|
|
128
|
+
*/
|
|
129
|
+
export async function isProcessRunning(pattern) {
|
|
130
|
+
try {
|
|
131
|
+
const { stdout } = await spawnAsync('pgrep', ['-f', pattern], { timeout: 2000 });
|
|
132
|
+
return stdout.trim().length > 0;
|
|
133
|
+
} catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get PID of a process by pattern
|
|
140
|
+
*/
|
|
141
|
+
export async function getProcessPid(pattern) {
|
|
142
|
+
try {
|
|
143
|
+
const { stdout } = await spawnAsync('pgrep', ['-f', pattern], { timeout: 2000 });
|
|
144
|
+
const pids = stdout.trim().split('\n').filter(Boolean).map(p => parseInt(p, 10));
|
|
145
|
+
return pids.length > 0 ? pids[0] : null;
|
|
146
|
+
} catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get all PIDs of a process by pattern
|
|
153
|
+
*/
|
|
154
|
+
export async function getAllProcessPids(pattern) {
|
|
155
|
+
try {
|
|
156
|
+
const { stdout } = await spawnAsync('pgrep', ['-f', pattern], { timeout: 2000 });
|
|
157
|
+
return stdout.trim().split('\n').filter(Boolean).map(p => parseInt(p, 10));
|
|
158
|
+
} catch {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Count processes matching pattern
|
|
165
|
+
*/
|
|
166
|
+
export async function countProcesses(pattern) {
|
|
167
|
+
try {
|
|
168
|
+
const pids = await getAllProcessPids(pattern);
|
|
169
|
+
return pids.length;
|
|
170
|
+
} catch {
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Kill a process by pattern
|
|
177
|
+
*/
|
|
178
|
+
export async function killProcess(pattern, signal = 'SIGTERM') {
|
|
179
|
+
try {
|
|
180
|
+
await spawnAsync('pkill', [signal === 'SIGKILL' ? '-9' : '', '-f', pattern].filter(Boolean), { timeout: 3000 });
|
|
181
|
+
return true;
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Check if a port is in use
|
|
189
|
+
*/
|
|
190
|
+
export async function isPortInUse(port) {
|
|
191
|
+
try {
|
|
192
|
+
await spawnAsync('lsof', ['-ti', `:${port}`], { timeout: 2000 });
|
|
193
|
+
return true;
|
|
194
|
+
} catch {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Kill process using a specific port
|
|
201
|
+
*/
|
|
202
|
+
export async function killProcessOnPort(port, force = false) {
|
|
203
|
+
try {
|
|
204
|
+
const { stdout } = await spawnAsync('lsof', ['-ti', `:${port}`], { timeout: 2000 });
|
|
205
|
+
const pids = stdout.trim().split('\n').filter(Boolean);
|
|
206
|
+
for (const pid of pids) {
|
|
207
|
+
try {
|
|
208
|
+
process.kill(parseInt(pid, 10), force ? 'SIGKILL' : 'SIGTERM');
|
|
209
|
+
} catch {}
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
} catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Check if a command/binary exists
|
|
219
|
+
*/
|
|
220
|
+
export async function commandExists(command) {
|
|
221
|
+
try {
|
|
222
|
+
await spawnAsync('which', [command], { timeout: 2000 });
|
|
223
|
+
return true;
|
|
224
|
+
} catch {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get process start time
|
|
231
|
+
*/
|
|
232
|
+
export async function getProcessStartTime(pid) {
|
|
233
|
+
try {
|
|
234
|
+
const { stdout } = await spawnAsync('ps', ['-p', String(pid), '-o', 'lstart='], { timeout: 1500 });
|
|
235
|
+
return stdout.trim() ? new Date(stdout.trim()).getTime() : null;
|
|
236
|
+
} catch {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ── File Locking Helpers ──────────────────────────────────────────────────
|
|
242
|
+
|
|
243
|
+
import lockfile from 'proper-lockfile';
|
|
244
|
+
import { promises as fsPromises } from 'node:fs';
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Write to a config file with proper locking to prevent corruption
|
|
248
|
+
*/
|
|
249
|
+
export async function writeConfigSafely(filePath, data) {
|
|
250
|
+
const lockOptions = {
|
|
251
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
252
|
+
stale: 5000,
|
|
253
|
+
realpath: false // Don't resolve symlinks
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
let release;
|
|
257
|
+
try {
|
|
258
|
+
// Ensure parent directory exists
|
|
259
|
+
const dir = filePath.substring(0, filePath.lastIndexOf('/'));
|
|
260
|
+
await fsPromises.mkdir(dir, { recursive: true });
|
|
261
|
+
|
|
262
|
+
// Create file if it doesn't exist
|
|
263
|
+
try {
|
|
264
|
+
await fsPromises.access(filePath);
|
|
265
|
+
} catch {
|
|
266
|
+
await fsPromises.writeFile(filePath, '{}');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Acquire lock
|
|
270
|
+
release = await lockfile.lock(filePath, lockOptions);
|
|
271
|
+
|
|
272
|
+
// Write data
|
|
273
|
+
const jsonData = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
|
|
274
|
+
await fsPromises.writeFile(filePath, jsonData, 'utf8');
|
|
275
|
+
|
|
276
|
+
return { ok: true };
|
|
277
|
+
} catch (err) {
|
|
278
|
+
return { ok: false, error: `Failed to write ${filePath}: ${err.message}` };
|
|
279
|
+
} finally {
|
|
280
|
+
if (release) {
|
|
281
|
+
try {
|
|
282
|
+
await release();
|
|
283
|
+
} catch {}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Read from a config file with proper locking
|
|
290
|
+
*/
|
|
291
|
+
export async function readConfigSafely(filePath) {
|
|
292
|
+
const lockOptions = {
|
|
293
|
+
retries: { retries: 3, minTimeout: 50, maxTimeout: 500 },
|
|
294
|
+
stale: 5000,
|
|
295
|
+
realpath: false
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
let release;
|
|
299
|
+
try {
|
|
300
|
+
// Check if file exists
|
|
301
|
+
try {
|
|
302
|
+
await fsPromises.access(filePath);
|
|
303
|
+
} catch {
|
|
304
|
+
return { ok: false, error: 'File does not exist' };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Acquire shared lock for reading
|
|
308
|
+
release = await lockfile.lock(filePath, { ...lockOptions, shared: true });
|
|
309
|
+
|
|
310
|
+
// Read and parse
|
|
311
|
+
const content = await fsPromises.readFile(filePath, 'utf8');
|
|
312
|
+
const data = JSON.parse(content);
|
|
313
|
+
|
|
314
|
+
return { ok: true, data };
|
|
315
|
+
} catch (err) {
|
|
316
|
+
return { ok: false, error: `Failed to read ${filePath}: ${err.message}` };
|
|
317
|
+
} finally {
|
|
318
|
+
if (release) {
|
|
319
|
+
try {
|
|
320
|
+
await release();
|
|
321
|
+
} catch {}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ── Error Handler Wrapper ─────────────────────────────────────────────────
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Wrap an async route handler with error handling
|
|
330
|
+
*/
|
|
331
|
+
export function asyncHandler(handler) {
|
|
332
|
+
return async (req, res, url) => {
|
|
333
|
+
try {
|
|
334
|
+
await handler(req, res, url);
|
|
335
|
+
} catch (err) {
|
|
336
|
+
console.error('[dashboard] Unhandled error:', err);
|
|
337
|
+
if (!res.headersSent) {
|
|
338
|
+
serverError(res, err.message, process.env.NODE_ENV === 'development' ? err.stack : undefined);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ── Path Sanitization ─────────────────────────────────────────────────────
|
|
345
|
+
|
|
346
|
+
import { resolve, normalize } from 'path';
|
|
347
|
+
import { homedir } from 'os';
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Validate that a path is safe (prevents path traversal attacks)
|
|
351
|
+
* Safe paths must be within the workspace or user's home directory
|
|
352
|
+
* @param {string} targetPath - Path to validate
|
|
353
|
+
* @param {string} workspaceRoot - Root of the workspace
|
|
354
|
+
* @returns {{ok: boolean, error?: string, sanitized?: string}}
|
|
355
|
+
*/
|
|
356
|
+
export function sanitizePath(targetPath, workspaceRoot) {
|
|
357
|
+
try {
|
|
358
|
+
if (!targetPath || typeof targetPath !== 'string') {
|
|
359
|
+
return { ok: false, error: 'Invalid path: must be a non-empty string' };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Normalize and resolve the path
|
|
363
|
+
const sanitized = normalize(resolve(targetPath));
|
|
364
|
+
const wsRoot = normalize(resolve(workspaceRoot));
|
|
365
|
+
const home = normalize(homedir());
|
|
366
|
+
|
|
367
|
+
// Check if path is within workspace or home directory
|
|
368
|
+
const inWorkspace = sanitized.startsWith(wsRoot + '/') || sanitized === wsRoot;
|
|
369
|
+
const inHome = sanitized.startsWith(home + '/') || sanitized === home;
|
|
370
|
+
|
|
371
|
+
if (!inWorkspace && !inHome) {
|
|
372
|
+
return {
|
|
373
|
+
ok: false,
|
|
374
|
+
error: `Path must be within workspace (${wsRoot}) or home directory (${home})`
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Block dangerous path components
|
|
379
|
+
const dangerous = ['..', '.git', 'node_modules/.bin'];
|
|
380
|
+
const parts = sanitized.split('/');
|
|
381
|
+
for (const danger of dangerous) {
|
|
382
|
+
if (parts.includes(danger)) {
|
|
383
|
+
return { ok: false, error: `Path contains dangerous component: ${danger}` };
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return { ok: true, sanitized };
|
|
388
|
+
} catch (err) {
|
|
389
|
+
return { ok: false, error: `Path validation failed: ${err.message}` };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod validation schemas for Dashboard API endpoints
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
// ── Common Schemas ────────────────────────────────────────────────────────
|
|
7
|
+
export const AgentIdSchema = z.string().min(1).max(50).regex(/^[a-z0-9-]+$/);
|
|
8
|
+
export const ProjectIdSchema = z.string().min(1).max(100);
|
|
9
|
+
export const ModelNameSchema = z.string().min(1).max(100);
|
|
10
|
+
|
|
11
|
+
// ── Agent Management ──────────────────────────────────────────────────────
|
|
12
|
+
export const SendMessageSchema = z.object({
|
|
13
|
+
to: AgentIdSchema,
|
|
14
|
+
message: z.string().min(1).max(10000),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const UpdateAgentConfigSchema = z.object({
|
|
18
|
+
agentId: AgentIdSchema,
|
|
19
|
+
model: ModelNameSchema.optional(),
|
|
20
|
+
fallbackModel: ModelNameSchema.optional(),
|
|
21
|
+
systemPrompt: z.string().max(50000).optional(),
|
|
22
|
+
name: z.string().max(100).optional(),
|
|
23
|
+
emoji: z.string().max(10).optional(),
|
|
24
|
+
theme: z.string().max(200).optional(),
|
|
25
|
+
toolProfile: z.enum(['crewswarm', 'basic', 'custom']).optional(),
|
|
26
|
+
alsoAllow: z.array(z.string()).optional(),
|
|
27
|
+
useOpenCode: z.boolean().optional(),
|
|
28
|
+
opencodeModel: z.string().optional(),
|
|
29
|
+
opencodeFallbackModel: z.string().optional(),
|
|
30
|
+
useCursorCli: z.boolean().optional(),
|
|
31
|
+
cursorCliModel: z.string().optional(),
|
|
32
|
+
useClaudeCode: z.boolean().optional(),
|
|
33
|
+
claudeCodeModel: z.string().optional(),
|
|
34
|
+
useCodex: z.boolean().optional(),
|
|
35
|
+
useGeminiCli: z.boolean().optional(),
|
|
36
|
+
geminiCliModel: z.string().optional(),
|
|
37
|
+
role: z.string().optional(),
|
|
38
|
+
opencodeLoop: z.boolean().optional(),
|
|
39
|
+
opencodeLoopMaxRounds: z.number().int().min(1).max(100).optional(),
|
|
40
|
+
workspace: z.string().optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const CreateAgentSchema = z.object({
|
|
44
|
+
id: AgentIdSchema,
|
|
45
|
+
model: ModelNameSchema,
|
|
46
|
+
name: z.string().max(100).optional(),
|
|
47
|
+
emoji: z.string().max(10).optional(),
|
|
48
|
+
theme: z.string().max(200).optional(),
|
|
49
|
+
systemPrompt: z.string().max(50000).optional(),
|
|
50
|
+
alsoAllow: z.array(z.string()).optional(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ── Project Management ────────────────────────────────────────────────────
|
|
54
|
+
export const CreateProjectSchema = z.object({
|
|
55
|
+
name: z.string().min(1).max(100),
|
|
56
|
+
description: z.string().max(1000).optional(),
|
|
57
|
+
outputDir: z.string().min(1).max(500).refine(
|
|
58
|
+
(p) => {
|
|
59
|
+
// Path sanitization: prevent traversal attacks
|
|
60
|
+
const { resolve } = require('node:path');
|
|
61
|
+
const { homedir } = require('node:os');
|
|
62
|
+
const resolved = resolve(p);
|
|
63
|
+
const cwd = resolve(process.cwd());
|
|
64
|
+
const home = resolve(homedir());
|
|
65
|
+
// Allow paths under workspace root OR user's home directory
|
|
66
|
+
return resolved.startsWith(cwd) || resolved.startsWith(home);
|
|
67
|
+
},
|
|
68
|
+
{ message: "outputDir must be under workspace root or home directory" }
|
|
69
|
+
),
|
|
70
|
+
featuresDoc: z.string().max(500).optional(),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export const UpdateProjectSchema = z.object({
|
|
74
|
+
projectId: ProjectIdSchema,
|
|
75
|
+
autoAdvance: z.boolean().optional(),
|
|
76
|
+
name: z.string().min(1).max(100).optional(),
|
|
77
|
+
description: z.string().max(1000).optional(),
|
|
78
|
+
outputDir: z.string().max(500).optional(),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export const DeleteProjectSchema = z.object({
|
|
82
|
+
projectId: ProjectIdSchema,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// ── Build Operations ──────────────────────────────────────────────────────
|
|
86
|
+
export const StartBuildSchema = z.object({
|
|
87
|
+
requirement: z.string().min(1).max(10000),
|
|
88
|
+
projectId: ProjectIdSchema.optional(),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export const StopBuildSchema = z.object({
|
|
92
|
+
projectId: ProjectIdSchema.optional(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// ── PM Loop ───────────────────────────────────────────────────────────────
|
|
96
|
+
export const StartPMLoopSchema = z.object({
|
|
97
|
+
dryRun: z.boolean().optional(),
|
|
98
|
+
projectId: ProjectIdSchema.optional(),
|
|
99
|
+
pmOptions: z.object({
|
|
100
|
+
autoAdvance: z.boolean().optional(),
|
|
101
|
+
maxIterations: z.number().int().min(1).max(1000).optional(),
|
|
102
|
+
useSecurity: z.boolean().optional(),
|
|
103
|
+
useQA: z.boolean().optional(),
|
|
104
|
+
}).optional(),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const StopPMLoopSchema = z.object({
|
|
108
|
+
projectId: ProjectIdSchema.optional(),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// ── Skills ────────────────────────────────────────────────────────────────
|
|
112
|
+
export const CreateSkillSchema = z.object({
|
|
113
|
+
name: z.string().min(1).max(100).regex(/^[a-zA-Z0-9_-]+$/),
|
|
114
|
+
url: z.string().url().max(1000),
|
|
115
|
+
method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']).optional(),
|
|
116
|
+
description: z.string().max(1000).optional(),
|
|
117
|
+
auth: z.object({
|
|
118
|
+
type: z.enum(['bearer', 'header', 'basic']).optional(),
|
|
119
|
+
keyFrom: z.string().optional(),
|
|
120
|
+
token: z.string().optional(),
|
|
121
|
+
header: z.string().optional(),
|
|
122
|
+
}).optional(),
|
|
123
|
+
defaultParams: z.record(z.any()).optional(),
|
|
124
|
+
requiresApproval: z.boolean().optional(),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export const DeleteSkillSchema = z.object({
|
|
128
|
+
name: z.string().min(1).max(100),
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
export const RunSkillSchema = z.object({
|
|
132
|
+
name: z.string().min(1).max(100),
|
|
133
|
+
params: z.record(z.any()).optional(),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export const ImportSkillSchema = z.object({
|
|
137
|
+
url: z.string().url().min(1).max(2000),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// ── Services ──────────────────────────────────────────────────────────────
|
|
141
|
+
export const ServiceActionSchema = z.object({
|
|
142
|
+
id: z.enum([
|
|
143
|
+
'rt-bus',
|
|
144
|
+
'agents',
|
|
145
|
+
'crew-lead',
|
|
146
|
+
'telegram',
|
|
147
|
+
'whatsapp',
|
|
148
|
+
'opencode',
|
|
149
|
+
'mcp',
|
|
150
|
+
'openclaw-gateway',
|
|
151
|
+
'dashboard',
|
|
152
|
+
]),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// ── Memory ────────────────────────────────────────────────────────────────
|
|
156
|
+
export const SearchMemorySchema = z.object({
|
|
157
|
+
query: z.string().min(1).max(500),
|
|
158
|
+
maxResults: z.number().int().min(1).max(100).optional(),
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// ── Benchmarks ────────────────────────────────────────────────────────────
|
|
162
|
+
export const RunBenchmarkSchema = z.object({
|
|
163
|
+
benchmarkId: z.string().min(1).max(100),
|
|
164
|
+
taskId: z.string().min(1).max(100),
|
|
165
|
+
model: ModelNameSchema.optional(),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// ── DLQ ───────────────────────────────────────────────────────────────────
|
|
169
|
+
export const ReplayDLQSchema = z.object({
|
|
170
|
+
key: z.string().min(1).max(200),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// ── Config ────────────────────────────────────────────────────────────────
|
|
174
|
+
export const UpdateConfigSchema = z.object({
|
|
175
|
+
rtToken: z.string().optional(),
|
|
176
|
+
telegramToken: z.string().optional(),
|
|
177
|
+
telegramChatIds: z.array(z.string()).optional(),
|
|
178
|
+
whatsappEnabled: z.boolean().optional(),
|
|
179
|
+
bgConsciousnessModel: z.string().optional(),
|
|
180
|
+
opencodeProject: z.string().optional(),
|
|
181
|
+
opencodeFallbackModel: z.string().optional(),
|
|
182
|
+
cursorCli: z.boolean().optional(),
|
|
183
|
+
cursorCliModel: z.string().optional(),
|
|
184
|
+
claudeCode: z.boolean().optional(),
|
|
185
|
+
claudeCodeModel: z.string().optional(),
|
|
186
|
+
geminiCli: z.boolean().optional(),
|
|
187
|
+
geminiCliModel: z.string().optional(),
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// ── Validation Helper ─────────────────────────────────────────────────────
|
|
191
|
+
export function validate(schema, data) {
|
|
192
|
+
try {
|
|
193
|
+
return { ok: true, data: schema.parse(data) };
|
|
194
|
+
} catch (err) {
|
|
195
|
+
const msg = err.issues?.[0]?.message || err.errors?.[0]?.message || err.message;
|
|
196
|
+
return { ok: false, error: msg };
|
|
197
|
+
}
|
|
198
|
+
}
|