@swarmclawai/swarmclaw 0.8.4 → 0.8.7
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/README.md +9 -9
- package/bin/swarmclaw.js +5 -1
- package/bin/worker-cmd.js +73 -0
- package/package.json +2 -1
- package/src/app/api/agents/[id]/route.ts +17 -7
- package/src/app/api/agents/route.ts +21 -8
- package/src/app/api/approvals/route.test.ts +6 -6
- package/src/app/api/approvals/route.ts +2 -1
- package/src/app/api/auth/route.ts +2 -3
- package/src/app/api/chatrooms/[id]/chat/route.test.ts +299 -0
- package/src/app/api/chatrooms/[id]/chat/route.ts +3 -2
- package/src/app/api/chatrooms/[id]/route.ts +7 -6
- package/src/app/api/chats/[id]/chat/route.test.ts +496 -0
- package/src/app/api/chats/[id]/chat/route.ts +7 -3
- package/src/app/api/chats/[id]/clear/route.ts +9 -9
- package/src/app/api/chats/[id]/devserver/route.ts +2 -1
- package/src/app/api/chats/[id]/edit-resend/route.ts +3 -4
- package/src/app/api/chats/[id]/fork/route.ts +3 -5
- package/src/app/api/chats/[id]/restore/route.ts +6 -7
- package/src/app/api/chats/[id]/retry/route.ts +3 -4
- package/src/app/api/chats/[id]/route.ts +61 -62
- package/src/app/api/chats/route.ts +7 -1
- package/src/app/api/connectors/[id]/route.ts +7 -8
- package/src/app/api/connectors/route.ts +5 -4
- package/src/app/api/eval/run/route.ts +2 -1
- package/src/app/api/eval/suite/route.ts +2 -1
- package/src/app/api/external-agents/route.test.ts +1 -1
- package/src/app/api/external-agents/route.ts +2 -2
- package/src/app/api/files/serve/route.ts +1 -1
- package/src/app/api/gateways/[id]/route.ts +7 -5
- package/src/app/api/gateways/route.ts +1 -1
- package/src/app/api/knowledge/upload/route.ts +1 -1
- package/src/app/api/logs/route.ts +5 -7
- package/src/app/api/memory-images/[filename]/route.ts +2 -3
- package/src/app/api/openclaw/agent-files/route.ts +4 -3
- package/src/app/api/openclaw/approvals/route.ts +3 -4
- package/src/app/api/openclaw/config-sync/route.ts +3 -2
- package/src/app/api/openclaw/cron/route.ts +3 -2
- package/src/app/api/openclaw/dotenv-keys/route.ts +2 -1
- package/src/app/api/openclaw/exec-config/route.ts +3 -2
- package/src/app/api/openclaw/gateway/route.ts +5 -4
- package/src/app/api/openclaw/history/route.ts +3 -2
- package/src/app/api/openclaw/media/route.ts +2 -1
- package/src/app/api/openclaw/permissions/route.ts +3 -2
- package/src/app/api/openclaw/sandbox-env/route.ts +3 -2
- package/src/app/api/openclaw/skills/install/route.ts +2 -1
- package/src/app/api/openclaw/skills/remove/route.ts +2 -1
- package/src/app/api/openclaw/skills/route.ts +3 -2
- package/src/app/api/orchestrator/run/route.ts +5 -14
- package/src/app/api/perf/route.ts +43 -0
- package/src/app/api/plugins/dependencies/route.ts +2 -1
- package/src/app/api/plugins/install/route.ts +2 -1
- package/src/app/api/plugins/marketplace/route.ts +3 -2
- package/src/app/api/plugins/settings/route.ts +2 -1
- package/src/app/api/preview-server/route.ts +11 -10
- package/src/app/api/projects/[id]/route.ts +1 -1
- package/src/app/api/schedules/[id]/route.test.ts +128 -0
- package/src/app/api/schedules/[id]/route.ts +43 -43
- package/src/app/api/schedules/[id]/run/route.ts +11 -62
- package/src/app/api/schedules/route.ts +21 -87
- package/src/app/api/settings/route.ts +2 -0
- package/src/app/api/setup/doctor/route.ts +9 -8
- package/src/app/api/tasks/[id]/approve/route.ts +33 -30
- package/src/app/api/tasks/[id]/route.ts +12 -35
- package/src/app/api/tasks/import/github/route.ts +2 -1
- package/src/app/api/tasks/route.ts +79 -91
- package/src/app/api/wallets/[id]/approve/route.ts +2 -1
- package/src/app/api/wallets/[id]/route.ts +13 -19
- package/src/app/api/wallets/[id]/send/route.ts +2 -1
- package/src/app/api/wallets/route.ts +2 -1
- package/src/app/api/webhooks/[id]/route.ts +2 -1
- package/src/app/api/webhooks/route.test.ts +3 -1
- package/src/app/page.tsx +23 -331
- package/src/cli/index.js +19 -0
- package/src/cli/index.ts +38 -7
- package/src/cli/spec.js +9 -0
- package/src/components/activity/activity-feed.tsx +7 -4
- package/src/components/agents/agent-card.tsx +32 -6
- package/src/components/agents/agent-chat-list.tsx +55 -22
- package/src/components/agents/agent-files-editor.tsx +3 -2
- package/src/components/agents/agent-sheet.tsx +123 -22
- package/src/components/agents/inspector-panel.tsx +1 -1
- package/src/components/agents/openclaw-skills-panel.tsx +2 -1
- package/src/components/agents/trash-list.tsx +1 -1
- package/src/components/auth/access-key-gate.tsx +8 -2
- package/src/components/auth/setup-wizard.tsx +10 -9
- package/src/components/auth/user-picker.tsx +3 -2
- package/src/components/chat/chat-area.tsx +20 -1
- package/src/components/chat/chat-card.tsx +18 -3
- package/src/components/chat/chat-header.tsx +24 -4
- package/src/components/chat/chat-list.tsx +2 -11
- package/src/components/chat/heartbeat-history-panel.tsx +2 -1
- package/src/components/chat/message-bubble.tsx +45 -6
- package/src/components/chat/message-list.tsx +280 -145
- package/src/components/chat/streaming-bubble.tsx +217 -60
- package/src/components/chat/swarm-panel.test.ts +274 -0
- package/src/components/chat/swarm-panel.tsx +410 -0
- package/src/components/chat/swarm-status-card.tsx +346 -0
- package/src/components/chat/tool-call-bubble.tsx +48 -23
- package/src/components/chatrooms/chatroom-list.tsx +8 -5
- package/src/components/chatrooms/chatroom-message.tsx +10 -7
- package/src/components/chatrooms/chatroom-view.tsx +12 -9
- package/src/components/connectors/connector-health.tsx +6 -4
- package/src/components/connectors/connector-list.tsx +16 -11
- package/src/components/connectors/connector-sheet.tsx +12 -6
- package/src/components/home/home-view.tsx +38 -24
- package/src/components/input/chat-input.tsx +10 -1
- package/src/components/layout/app-layout.tsx +2 -38
- package/src/components/layout/sheet-layer.tsx +50 -0
- package/src/components/mcp-servers/mcp-server-list.tsx +37 -5
- package/src/components/mcp-servers/mcp-server-sheet.tsx +12 -2
- package/src/components/plugins/plugin-list.tsx +8 -4
- package/src/components/plugins/plugin-sheet.tsx +2 -1
- package/src/components/providers/provider-list.tsx +3 -2
- package/src/components/providers/provider-sheet.tsx +2 -1
- package/src/components/runs/run-list.tsx +11 -7
- package/src/components/schedules/schedule-card.tsx +5 -3
- package/src/components/shared/agent-switch-dialog.tsx +1 -1
- package/src/components/shared/attachment-chip.tsx +19 -3
- package/src/components/shared/notification-center.tsx +6 -3
- package/src/components/shared/settings/plugin-manager.tsx +3 -2
- package/src/components/shared/settings/section-embedding.tsx +2 -1
- package/src/components/shared/settings/section-orchestrator.tsx +2 -1
- package/src/components/shared/settings/section-user-preferences.tsx +107 -0
- package/src/components/shared/settings/settings-page.tsx +13 -9
- package/src/components/skills/clawhub-browser.tsx +15 -4
- package/src/components/skills/skill-list.tsx +15 -4
- package/src/components/tasks/approvals-panel.tsx +2 -1
- package/src/components/tasks/task-board.tsx +35 -37
- package/src/components/tasks/task-sheet.tsx +4 -3
- package/src/components/ui/full-screen-loader.tsx +164 -0
- package/src/components/wallets/wallet-approval-dialog.tsx +2 -1
- package/src/components/wallets/wallet-panel.tsx +6 -5
- package/src/components/wallets/wallet-section.tsx +3 -2
- package/src/components/webhooks/webhook-list.tsx +4 -5
- package/src/components/webhooks/webhook-sheet.tsx +6 -6
- package/src/hooks/use-app-bootstrap.ts +202 -0
- package/src/hooks/use-mounted-ref.ts +14 -0
- package/src/hooks/use-now.ts +31 -0
- package/src/hooks/use-openclaw-gateway.ts +2 -1
- package/src/instrumentation.ts +20 -8
- package/src/lib/agent-default-tools.test.ts +52 -0
- package/src/lib/agent-default-tools.ts +40 -0
- package/src/lib/api-client.test.ts +21 -0
- package/src/lib/api-client.ts +6 -11
- package/src/lib/canvas-content.test.ts +360 -0
- package/src/lib/chat-streaming-state.test.ts +49 -2
- package/src/lib/chat-streaming-state.ts +26 -10
- package/src/lib/fetch-timeout.test.ts +54 -0
- package/src/lib/fetch-timeout.ts +60 -3
- package/src/lib/live-tool-events.test.ts +77 -0
- package/src/lib/live-tool-events.ts +73 -0
- package/src/lib/local-observability.test.ts +2 -2
- package/src/lib/openclaw-endpoint.test.ts +1 -1
- package/src/lib/providers/anthropic.ts +12 -16
- package/src/lib/providers/index.ts +4 -2
- package/src/lib/providers/ollama.ts +9 -6
- package/src/lib/providers/openai.ts +11 -14
- package/src/lib/runtime-env.test.ts +8 -8
- package/src/lib/schedule-dedupe-advanced.test.ts +2 -2
- package/src/lib/schedule-dedupe.test.ts +1 -1
- package/src/lib/schedule-dedupe.ts +3 -2
- package/src/lib/server/agent-thread-session.test.ts +6 -6
- package/src/lib/server/agent-thread-session.ts +6 -9
- package/src/lib/server/alert-dispatch.ts +2 -1
- package/src/lib/server/api-routes.test.ts +6 -6
- package/src/lib/server/approval-connector-notify.test.ts +4 -4
- package/src/lib/server/approvals-auto-approve.test.ts +29 -29
- package/src/lib/server/approvals.test.ts +317 -0
- package/src/lib/server/approvals.ts +5 -4
- package/src/lib/server/autonomy-runtime.test.ts +11 -11
- package/src/lib/server/browser-state.ts +2 -2
- package/src/lib/server/capability-router.test.ts +1 -1
- package/src/lib/server/capability-router.ts +3 -2
- package/src/lib/server/chat-execution-advanced.test.ts +15 -2
- package/src/lib/server/chat-execution-connector-delivery.ts +67 -0
- package/src/lib/server/chat-execution-disabled.test.ts +3 -3
- package/src/lib/server/chat-execution-eval-history.test.ts +3 -3
- package/src/lib/server/chat-execution-heartbeat.test.ts +42 -1
- package/src/lib/server/chat-execution-session-sync.test.ts +119 -0
- package/src/lib/server/chat-execution-tool-events.ts +116 -0
- package/src/lib/server/chat-execution-utils.test.ts +479 -0
- package/src/lib/server/chat-execution-utils.ts +533 -0
- package/src/lib/server/chat-execution.ts +153 -748
- package/src/lib/server/chat-streaming-utils.ts +174 -0
- package/src/lib/server/chat-turn-tool-routing.ts +310 -0
- package/src/lib/server/chatroom-session-persistence.test.ts +2 -2
- package/src/lib/server/clawhub-client.ts +2 -1
- package/src/lib/server/collection-helpers.test.ts +92 -0
- package/src/lib/server/collection-helpers.ts +25 -3
- package/src/lib/server/connectors/access.ts +146 -0
- package/src/lib/server/connectors/bluebubbles.test.ts +1 -1
- package/src/lib/server/connectors/bluebubbles.ts +4 -4
- package/src/lib/server/connectors/commands.ts +367 -0
- package/src/lib/server/connectors/connector-routing.test.ts +4 -4
- package/src/lib/server/connectors/delivery.ts +142 -0
- package/src/lib/server/connectors/discord.ts +37 -40
- package/src/lib/server/connectors/email.ts +11 -10
- package/src/lib/server/connectors/googlechat.ts +4 -4
- package/src/lib/server/connectors/inbound-audio-transcription.ts +2 -1
- package/src/lib/server/connectors/ingress-delivery.ts +23 -0
- package/src/lib/server/connectors/manager-roundtrip.test.ts +300 -0
- package/src/lib/server/connectors/manager.test.ts +352 -77
- package/src/lib/server/connectors/manager.ts +134 -673
- package/src/lib/server/connectors/matrix.ts +4 -4
- package/src/lib/server/connectors/message-sentinel.ts +7 -0
- package/src/lib/server/connectors/openclaw.test.ts +1 -1
- package/src/lib/server/connectors/openclaw.ts +8 -10
- package/src/lib/server/connectors/outbox.test.ts +192 -0
- package/src/lib/server/connectors/outbox.ts +369 -0
- package/src/lib/server/connectors/pairing.test.ts +18 -1
- package/src/lib/server/connectors/pairing.ts +49 -4
- package/src/lib/server/connectors/policy.ts +9 -3
- package/src/lib/server/connectors/reconnect-state.ts +71 -0
- package/src/lib/server/connectors/response-media.ts +256 -0
- package/src/lib/server/connectors/runtime-state.ts +67 -0
- package/src/lib/server/connectors/session.test.ts +357 -0
- package/src/lib/server/connectors/session.ts +422 -0
- package/src/lib/server/connectors/signal.ts +7 -7
- package/src/lib/server/connectors/slack.ts +43 -43
- package/src/lib/server/connectors/teams.ts +4 -4
- package/src/lib/server/connectors/telegram.ts +37 -43
- package/src/lib/server/connectors/types.ts +31 -1
- package/src/lib/server/connectors/whatsapp.test.ts +108 -0
- package/src/lib/server/connectors/whatsapp.ts +106 -34
- package/src/lib/server/context-manager.test.ts +409 -0
- package/src/lib/server/cost.test.ts +1 -1
- package/src/lib/server/daemon-policy.ts +78 -0
- package/src/lib/server/daemon-state-connectors.test.ts +167 -0
- package/src/lib/server/daemon-state.test.ts +283 -55
- package/src/lib/server/daemon-state.ts +106 -109
- package/src/lib/server/data-dir.test.ts +5 -5
- package/src/lib/server/data-dir.ts +4 -0
- package/src/lib/server/delegation-jobs-advanced.test.ts +1 -1
- package/src/lib/server/delegation-jobs.test.ts +87 -0
- package/src/lib/server/delegation-jobs.ts +42 -48
- package/src/lib/server/devserver-launch.ts +1 -1
- package/src/lib/server/document-utils.ts +7 -9
- package/src/lib/server/elevenlabs.ts +2 -1
- package/src/lib/server/embeddings.test.ts +105 -0
- package/src/lib/server/ethereum.ts +3 -2
- package/src/lib/server/eval/agent-regression.ts +3 -2
- package/src/lib/server/eval/runner.ts +2 -1
- package/src/lib/server/eval/scorer.ts +2 -1
- package/src/lib/server/evm-swap.ts +2 -1
- package/src/lib/server/gateway/protocol.test.ts +1 -1
- package/src/lib/server/guardian.ts +2 -1
- package/src/lib/server/heartbeat-blocked-suppression.test.ts +151 -0
- package/src/lib/server/heartbeat-service-timer.test.ts +6 -6
- package/src/lib/server/heartbeat-service.test.ts +406 -0
- package/src/lib/server/heartbeat-service.ts +54 -7
- package/src/lib/server/heartbeat-wake.test.ts +19 -0
- package/src/lib/server/heartbeat-wake.ts +17 -16
- package/src/lib/server/integrity-monitor.test.ts +149 -0
- package/src/lib/server/json-utils.ts +22 -0
- package/src/lib/server/knowledge-db.test.ts +13 -13
- package/src/lib/server/link-understanding.ts +2 -1
- package/src/lib/server/llm-response-cache.test.ts +1 -1
- package/src/lib/server/main-agent-loop-advanced.test.ts +65 -3
- package/src/lib/server/main-agent-loop.test.ts +6 -6
- package/src/lib/server/main-agent-loop.ts +21 -7
- package/src/lib/server/mcp-client.test.ts +1 -1
- package/src/lib/server/mcp-conformance.test.ts +1 -1
- package/src/lib/server/mcp-conformance.ts +3 -2
- package/src/lib/server/memory-consolidation.ts +2 -1
- package/src/lib/server/memory-db.test.ts +485 -0
- package/src/lib/server/memory-db.ts +39 -26
- package/src/lib/server/memory-graph.test.ts +2 -2
- package/src/lib/server/memory-policy.test.ts +7 -7
- package/src/lib/server/memory-retrieval.test.ts +1 -1
- package/src/lib/server/openclaw-config-sync.ts +2 -1
- package/src/lib/server/openclaw-deploy.test.ts +1 -1
- package/src/lib/server/openclaw-deploy.ts +8 -12
- package/src/lib/server/openclaw-exec-config.ts +2 -1
- package/src/lib/server/openclaw-gateway.ts +6 -7
- package/src/lib/server/openclaw-skills-normalize.ts +2 -1
- package/src/lib/server/openclaw-sync.ts +7 -5
- package/src/lib/server/orchestrator-lg-structure.test.ts +17 -0
- package/src/lib/server/orchestrator-lg.ts +199 -327
- package/src/lib/server/path-utils.ts +31 -0
- package/src/lib/server/perf.ts +161 -0
- package/src/lib/server/plugins-approval-guidance.ts +115 -0
- package/src/lib/server/plugins.test.ts +1 -1
- package/src/lib/server/plugins.ts +22 -132
- package/src/lib/server/process-manager.ts +5 -8
- package/src/lib/server/provider-health.test.ts +137 -0
- package/src/lib/server/provider-health.ts +3 -3
- package/src/lib/server/provider-model-discovery.ts +3 -12
- package/src/lib/server/queue-followups.test.ts +9 -9
- package/src/lib/server/queue-reconcile.test.ts +2 -2
- package/src/lib/server/queue-recovery.test.ts +269 -0
- package/src/lib/server/queue.test.ts +570 -0
- package/src/lib/server/queue.ts +62 -455
- package/src/lib/server/resolve-image.ts +30 -0
- package/src/lib/server/runtime-settings.test.ts +4 -4
- package/src/lib/server/runtime-storage-write-paths.test.ts +60 -0
- package/src/lib/server/schedule-normalization.test.ts +279 -0
- package/src/lib/server/schedule-service.ts +263 -0
- package/src/lib/server/scheduler.ts +17 -74
- package/src/lib/server/session-mailbox.test.ts +191 -0
- package/src/lib/server/session-run-manager.test.ts +640 -0
- package/src/lib/server/session-run-manager.ts +59 -15
- package/src/lib/server/session-tools/autonomy-tools.test.ts +20 -20
- package/src/lib/server/session-tools/calendar.ts +2 -1
- package/src/lib/server/session-tools/canvas.ts +2 -1
- package/src/lib/server/session-tools/chatroom.ts +2 -1
- package/src/lib/server/session-tools/connector.ts +26 -28
- package/src/lib/server/session-tools/context-mgmt.ts +3 -2
- package/src/lib/server/session-tools/crawl.ts +4 -3
- package/src/lib/server/session-tools/crud.ts +105 -324
- package/src/lib/server/session-tools/delegate-fallback.test.ts +9 -9
- package/src/lib/server/session-tools/delegate.ts +6 -8
- package/src/lib/server/session-tools/discovery-approvals.test.ts +15 -15
- package/src/lib/server/session-tools/discovery.ts +4 -3
- package/src/lib/server/session-tools/document.ts +2 -1
- package/src/lib/server/session-tools/email.ts +2 -1
- package/src/lib/server/session-tools/extract.ts +2 -1
- package/src/lib/server/session-tools/file.ts +4 -3
- package/src/lib/server/session-tools/http.ts +2 -1
- package/src/lib/server/session-tools/human-loop.ts +2 -1
- package/src/lib/server/session-tools/image-gen.ts +4 -3
- package/src/lib/server/session-tools/index.ts +26 -30
- package/src/lib/server/session-tools/mailbox.ts +2 -1
- package/src/lib/server/session-tools/manage-connectors.test.ts +4 -4
- package/src/lib/server/session-tools/manage-schedules.test.ts +12 -12
- package/src/lib/server/session-tools/manage-tasks-advanced.test.ts +5 -5
- package/src/lib/server/session-tools/manage-tasks.test.ts +2 -2
- package/src/lib/server/session-tools/monitor.ts +2 -1
- package/src/lib/server/session-tools/platform.ts +2 -1
- package/src/lib/server/session-tools/plugin-creator.ts +2 -1
- package/src/lib/server/session-tools/replicate.ts +3 -2
- package/src/lib/server/session-tools/session-tools-wiring.test.ts +6 -6
- package/src/lib/server/session-tools/shell.ts +4 -9
- package/src/lib/server/session-tools/subagent.ts +322 -170
- package/src/lib/server/session-tools/table.ts +6 -5
- package/src/lib/server/session-tools/wallet-tool.test.ts +3 -3
- package/src/lib/server/session-tools/wallet.ts +7 -6
- package/src/lib/server/session-tools/web-browser-config.test.ts +1 -0
- package/src/lib/server/session-tools/web-utils.ts +317 -0
- package/src/lib/server/session-tools/web.ts +62 -328
- package/src/lib/server/skill-prompt-budget.test.ts +1 -1
- package/src/lib/server/skills-normalize.ts +2 -1
- package/src/lib/server/storage-item-access.test.ts +302 -0
- package/src/lib/server/storage.ts +366 -314
- package/src/lib/server/stream-agent-chat.test.ts +82 -3
- package/src/lib/server/stream-agent-chat.ts +146 -510
- package/src/lib/server/stream-continuation.ts +412 -0
- package/src/lib/server/subagent-lineage.test.ts +647 -0
- package/src/lib/server/subagent-lineage.ts +435 -0
- package/src/lib/server/subagent-runtime.test.ts +484 -0
- package/src/lib/server/subagent-runtime.ts +419 -0
- package/src/lib/server/subagent-swarm.test.ts +391 -0
- package/src/lib/server/subagent-swarm.ts +564 -0
- package/src/lib/server/system-events.ts +3 -3
- package/src/lib/server/task-followups.test.ts +491 -0
- package/src/lib/server/task-followups.ts +391 -0
- package/src/lib/server/task-lifecycle.test.ts +205 -0
- package/src/lib/server/task-lifecycle.ts +200 -0
- package/src/lib/server/task-quality-gate.test.ts +1 -1
- package/src/lib/server/task-resume.ts +208 -0
- package/src/lib/server/task-service.test.ts +108 -0
- package/src/lib/server/task-service.ts +264 -0
- package/src/lib/server/task-validation.test.ts +1 -1
- package/src/lib/server/test-utils/run-with-temp-data-dir.ts +42 -0
- package/src/lib/server/tool-capability-policy.test.ts +2 -2
- package/src/lib/server/tool-capability-policy.ts +3 -2
- package/src/lib/server/tool-planning.ts +2 -1
- package/src/lib/server/tool-retry.ts +2 -3
- package/src/lib/server/wake-dispatcher.test.ts +303 -0
- package/src/lib/server/wake-dispatcher.ts +318 -0
- package/src/lib/server/wake-mode.test.ts +161 -0
- package/src/lib/server/wake-mode.ts +174 -0
- package/src/lib/server/wallet-service.ts +8 -9
- package/src/lib/server/watch-jobs.ts +2 -1
- package/src/lib/server/workspace-context.ts +2 -2
- package/src/lib/shared-utils.test.ts +142 -0
- package/src/lib/shared-utils.ts +62 -0
- package/src/lib/tool-event-summary.ts +2 -1
- package/src/lib/view-routes.test.ts +100 -0
- package/src/lib/wallet.test.ts +322 -6
- package/src/proxy.test.ts +4 -4
- package/src/proxy.ts +2 -3
- package/src/stores/set-if-changed.ts +40 -0
- package/src/stores/slices/agent-slice.ts +111 -0
- package/src/stores/slices/auth-slice.ts +25 -0
- package/src/stores/slices/data-slice.ts +301 -0
- package/src/stores/slices/index.ts +7 -0
- package/src/stores/slices/session-slice.ts +112 -0
- package/src/stores/slices/task-slice.ts +63 -0
- package/src/stores/slices/ui-slice.ts +192 -0
- package/src/stores/use-app-store.ts +17 -822
- package/src/stores/use-approval-store.ts +2 -1
- package/src/stores/use-chat-store.ts +8 -1
- package/src/types/index.ts +10 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { detectConfigIssues, repairConfigIssue } from '@/lib/server/openclaw-config-sync'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** GET — detect configuration issues */
|
|
5
6
|
export async function GET() {
|
|
@@ -7,7 +8,7 @@ export async function GET() {
|
|
|
7
8
|
const issues = await detectConfigIssues()
|
|
8
9
|
return NextResponse.json({ issues })
|
|
9
10
|
} catch (err: unknown) {
|
|
10
|
-
const message =
|
|
11
|
+
const message = errorMessage(err)
|
|
11
12
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -27,7 +28,7 @@ export async function POST(req: Request) {
|
|
|
27
28
|
}
|
|
28
29
|
return NextResponse.json({ ok: true })
|
|
29
30
|
} catch (err: unknown) {
|
|
30
|
-
const message =
|
|
31
|
+
const message = errorMessage(err)
|
|
31
32
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
3
|
import type { GatewayCronJob } from '@/types'
|
|
4
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
4
5
|
|
|
5
6
|
/** GET — list all cron jobs from gateway */
|
|
6
7
|
export async function GET() {
|
|
@@ -13,7 +14,7 @@ export async function GET() {
|
|
|
13
14
|
const result = await gw.rpc('cron.list', { includeDisabled: true }) as GatewayCronJob[] | undefined
|
|
14
15
|
return NextResponse.json(result ?? [])
|
|
15
16
|
} catch (err: unknown) {
|
|
16
|
-
const message =
|
|
17
|
+
const message = errorMessage(err)
|
|
17
18
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
18
19
|
}
|
|
19
20
|
}
|
|
@@ -46,7 +47,7 @@ export async function POST(req: Request) {
|
|
|
46
47
|
return NextResponse.json({ error: `Unknown action: ${action}` }, { status: 400 })
|
|
47
48
|
}
|
|
48
49
|
} catch (err: unknown) {
|
|
49
|
-
const message =
|
|
50
|
+
const message = errorMessage(err)
|
|
50
51
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
51
52
|
}
|
|
52
53
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** GET — list env var keys from gateway .env */
|
|
5
6
|
export async function GET() {
|
|
@@ -12,7 +13,7 @@ export async function GET() {
|
|
|
12
13
|
const result = await gw.rpc('env.keys') as string[] | undefined
|
|
13
14
|
return NextResponse.json(result ?? [])
|
|
14
15
|
} catch (err: unknown) {
|
|
15
|
-
const message =
|
|
16
|
+
const message = errorMessage(err)
|
|
16
17
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getExecConfig, setExecConfig } from '@/lib/server/openclaw-exec-config'
|
|
3
3
|
import type { ExecApprovalConfig } from '@/types'
|
|
4
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
4
5
|
|
|
5
6
|
/** GET ?agentId=X — fetch exec approval config */
|
|
6
7
|
export async function GET(req: Request) {
|
|
@@ -14,7 +15,7 @@ export async function GET(req: Request) {
|
|
|
14
15
|
const snapshot = await getExecConfig(agentId)
|
|
15
16
|
return NextResponse.json(snapshot)
|
|
16
17
|
} catch (err: unknown) {
|
|
17
|
-
const message =
|
|
18
|
+
const message = errorMessage(err)
|
|
18
19
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
19
20
|
}
|
|
20
21
|
}
|
|
@@ -35,7 +36,7 @@ export async function PUT(req: Request) {
|
|
|
35
36
|
const result = await setExecConfig(agentId, config, baseHash ?? '')
|
|
36
37
|
return NextResponse.json(result)
|
|
37
38
|
} catch (err: unknown) {
|
|
38
|
-
const message =
|
|
39
|
+
const message = errorMessage(err)
|
|
39
40
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
40
41
|
}
|
|
41
42
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected, getGateway, disconnectGateway, manualConnect } from '@/lib/server/openclaw-gateway'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** POST — proxy an RPC call or perform gateway actions */
|
|
5
6
|
export async function POST(req: Request) {
|
|
@@ -18,7 +19,7 @@ export async function POST(req: Request) {
|
|
|
18
19
|
const ok = await manualConnect(url, token, profileId)
|
|
19
20
|
return NextResponse.json({ ok })
|
|
20
21
|
} catch (err: unknown) {
|
|
21
|
-
return NextResponse.json({ ok: false, error:
|
|
22
|
+
return NextResponse.json({ ok: false, error: errorMessage(err) }, { status: 502 })
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -36,7 +37,7 @@ export async function POST(req: Request) {
|
|
|
36
37
|
const mode = (config as Record<string, unknown>)?.reloadMode ?? 'hot'
|
|
37
38
|
return NextResponse.json({ ok: true, result: mode })
|
|
38
39
|
} catch (err: unknown) {
|
|
39
|
-
return NextResponse.json({ error:
|
|
40
|
+
return NextResponse.json({ error: errorMessage(err) }, { status: 502 })
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -47,7 +48,7 @@ export async function POST(req: Request) {
|
|
|
47
48
|
await gw.rpc('config.set', { reloadMode: params?.mode })
|
|
48
49
|
return NextResponse.json({ ok: true })
|
|
49
50
|
} catch (err: unknown) {
|
|
50
|
-
return NextResponse.json({ error:
|
|
51
|
+
return NextResponse.json({ error: errorMessage(err) }, { status: 502 })
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -61,7 +62,7 @@ export async function POST(req: Request) {
|
|
|
61
62
|
const result = await gw.rpc(method, params)
|
|
62
63
|
return NextResponse.json({ ok: true, result })
|
|
63
64
|
} catch (err: unknown) {
|
|
64
|
-
const message =
|
|
65
|
+
const message = errorMessage(err)
|
|
65
66
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -4,6 +4,7 @@ import { mergeHistoryMessages, isValidSessionKey } from '@/lib/server/openclaw-h
|
|
|
4
4
|
import { loadSessions, saveSessions } from '@/lib/server/storage'
|
|
5
5
|
import { notify } from '@/lib/server/ws-hub'
|
|
6
6
|
import type { GatewaySessionPreview } from '@/types'
|
|
7
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Extract a single session preview from the gateway response.
|
|
@@ -58,7 +59,7 @@ export async function GET(req: Request) {
|
|
|
58
59
|
const preview = extractPreview(raw, sessionKey)
|
|
59
60
|
return NextResponse.json(preview ?? { sessionKey, epoch: 0, messages: [] })
|
|
60
61
|
} catch (err: unknown) {
|
|
61
|
-
const message =
|
|
62
|
+
const message = errorMessage(err)
|
|
62
63
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
63
64
|
}
|
|
64
65
|
}
|
|
@@ -103,7 +104,7 @@ export async function POST(req: Request) {
|
|
|
103
104
|
|
|
104
105
|
return NextResponse.json({ ok: true, merged: newCount })
|
|
105
106
|
} catch (err: unknown) {
|
|
106
|
-
const message =
|
|
107
|
+
const message = errorMessage(err)
|
|
107
108
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
108
109
|
}
|
|
109
110
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
3
|
import { lookup } from 'mime-types'
|
|
4
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
4
5
|
|
|
5
6
|
const MAX_SIZE = 25 * 1024 * 1024 // 25MB
|
|
6
7
|
|
|
@@ -47,7 +48,7 @@ export async function GET(req: Request) {
|
|
|
47
48
|
},
|
|
48
49
|
})
|
|
49
50
|
} catch (err: unknown) {
|
|
50
|
-
const message =
|
|
51
|
+
const message = errorMessage(err)
|
|
51
52
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'
|
|
|
2
2
|
import type { PermissionPreset } from '@/types'
|
|
3
3
|
import { getExecConfig } from '@/lib/server/openclaw-exec-config'
|
|
4
4
|
import { resolvePresetFromConfig, applyPreset } from '@/lib/server/openclaw-permission-presets'
|
|
5
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
5
6
|
|
|
6
7
|
/** GET ?agentId=X — resolve current permission preset */
|
|
7
8
|
export async function GET(req: Request) {
|
|
@@ -16,7 +17,7 @@ export async function GET(req: Request) {
|
|
|
16
17
|
const preset = resolvePresetFromConfig(snap.file)
|
|
17
18
|
return NextResponse.json({ preset, config: snap.file })
|
|
18
19
|
} catch (err: unknown) {
|
|
19
|
-
const message =
|
|
20
|
+
const message = errorMessage(err)
|
|
20
21
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -33,7 +34,7 @@ export async function PUT(req: Request) {
|
|
|
33
34
|
await applyPreset(agentId, preset)
|
|
34
35
|
return NextResponse.json({ ok: true })
|
|
35
36
|
} catch (err: unknown) {
|
|
36
|
-
const message =
|
|
37
|
+
const message = errorMessage(err)
|
|
37
38
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
38
39
|
}
|
|
39
40
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** GET — list available and allowed env keys for sandbox */
|
|
5
6
|
export async function GET() {
|
|
@@ -29,7 +30,7 @@ export async function GET() {
|
|
|
29
30
|
|
|
30
31
|
return NextResponse.json({ available: available ?? [], allowed })
|
|
31
32
|
} catch (err: unknown) {
|
|
32
|
-
const message =
|
|
33
|
+
const message = errorMessage(err)
|
|
33
34
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -63,7 +64,7 @@ export async function PUT(req: Request) {
|
|
|
63
64
|
|
|
64
65
|
return NextResponse.json({ ok: true })
|
|
65
66
|
} catch (err: unknown) {
|
|
66
|
-
const message =
|
|
67
|
+
const message = errorMessage(err)
|
|
67
68
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** POST { name, installId, timeoutMs? } — install a skill via gateway */
|
|
5
6
|
export async function POST(req: Request) {
|
|
@@ -26,7 +27,7 @@ export async function POST(req: Request) {
|
|
|
26
27
|
}, (timeoutMs ?? 120_000) + 5_000)
|
|
27
28
|
return NextResponse.json({ ok: true, result })
|
|
28
29
|
} catch (err: unknown) {
|
|
29
|
-
const message =
|
|
30
|
+
const message = errorMessage(err)
|
|
30
31
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { ensureGatewayConnected } from '@/lib/server/openclaw-gateway'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
/** POST { skillKey, source } — remove a skill via gateway */
|
|
5
6
|
export async function POST(req: Request) {
|
|
@@ -18,7 +19,7 @@ export async function POST(req: Request) {
|
|
|
18
19
|
await gw.rpc('skills.remove', { skillKey, source })
|
|
19
20
|
return NextResponse.json({ ok: true })
|
|
20
21
|
} catch (err: unknown) {
|
|
21
|
-
const message =
|
|
22
|
+
const message = errorMessage(err)
|
|
22
23
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -5,6 +5,7 @@ import { normalizeOpenClawSkillsPayload } from '@/lib/server/openclaw-skills-nor
|
|
|
5
5
|
import { loadAgents, saveAgents } from '@/lib/server/storage'
|
|
6
6
|
import { notify } from '@/lib/server/ws-hub'
|
|
7
7
|
import type { SkillAllowlistMode } from '@/types'
|
|
8
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
8
9
|
|
|
9
10
|
/** GET ?agentId=X — fetch skills from gateway with eligibility */
|
|
10
11
|
export async function GET(req: Request) {
|
|
@@ -24,7 +25,7 @@ export async function GET(req: Request) {
|
|
|
24
25
|
const result = await gw.rpc('skills.status', { agentId: gatewayAgentId }) as unknown
|
|
25
26
|
return NextResponse.json(normalizeOpenClawSkillsPayload(result))
|
|
26
27
|
} catch (err: unknown) {
|
|
27
|
-
const message =
|
|
28
|
+
const message = errorMessage(err)
|
|
28
29
|
const status = message.includes('not an OpenClaw agent')
|
|
29
30
|
? 400
|
|
30
31
|
: message.includes('not found')
|
|
@@ -55,7 +56,7 @@ export async function PATCH(req: Request) {
|
|
|
55
56
|
await gw.rpc('skills.update', { skillKey, enabled, apiKey })
|
|
56
57
|
return NextResponse.json({ ok: true })
|
|
57
58
|
} catch (err: unknown) {
|
|
58
|
-
const message =
|
|
59
|
+
const message = errorMessage(err)
|
|
59
60
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { genId } from '@/lib/id'
|
|
3
|
-
import { loadAgents,
|
|
3
|
+
import { loadAgents, upsertTask } from '@/lib/server/storage'
|
|
4
4
|
import { enqueueTask } from '@/lib/server/queue'
|
|
5
|
+
import { buildBoardTask } from '@/lib/server/task-lifecycle'
|
|
5
6
|
|
|
6
7
|
export async function POST(req: Request) {
|
|
7
8
|
const { agentId, task } = await req.json().catch(() => ({}))
|
|
@@ -18,23 +19,13 @@ export async function POST(req: Request) {
|
|
|
18
19
|
// Create a board task and enqueue it
|
|
19
20
|
const taskId = genId()
|
|
20
21
|
const now = Date.now()
|
|
21
|
-
|
|
22
|
-
tasks[taskId] = {
|
|
22
|
+
upsertTask(taskId, buildBoardTask({
|
|
23
23
|
id: taskId,
|
|
24
24
|
title: task.slice(0, 80),
|
|
25
25
|
description: task,
|
|
26
|
-
status: 'backlog',
|
|
27
26
|
agentId,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
error: null,
|
|
31
|
-
createdAt: now,
|
|
32
|
-
updatedAt: now,
|
|
33
|
-
queuedAt: null,
|
|
34
|
-
startedAt: null,
|
|
35
|
-
completedAt: null,
|
|
36
|
-
}
|
|
37
|
-
saveTasks(tasks)
|
|
27
|
+
now,
|
|
28
|
+
}))
|
|
38
29
|
|
|
39
30
|
// Enqueue — this sets status to queued and kicks the worker
|
|
40
31
|
enqueueTask(taskId)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { perf } from '@/lib/server/perf'
|
|
3
|
+
|
|
4
|
+
export const dynamic = 'force-dynamic'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* GET /api/perf — Returns recent perf entries and current state.
|
|
8
|
+
* POST /api/perf — Enable/disable perf tracing or clear entries.
|
|
9
|
+
*
|
|
10
|
+
* Only active when SWARMCLAW_PERF=1 or after POST {action:'enable'}.
|
|
11
|
+
* Workbench tests use this to activate tracing and collect results.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export function GET() {
|
|
15
|
+
return NextResponse.json({
|
|
16
|
+
enabled: perf.isEnabled(),
|
|
17
|
+
entries: perf.getRecentEntries(),
|
|
18
|
+
count: perf.getRecentEntries().length,
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function POST(req: Request) {
|
|
23
|
+
const body = await req.json().catch(() => ({})) as Record<string, unknown>
|
|
24
|
+
const action = body.action
|
|
25
|
+
|
|
26
|
+
if (action === 'enable') {
|
|
27
|
+
perf.setEnabled(true)
|
|
28
|
+
perf.clearRecentEntries()
|
|
29
|
+
return NextResponse.json({ enabled: true })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (action === 'disable') {
|
|
33
|
+
perf.setEnabled(false)
|
|
34
|
+
return NextResponse.json({ enabled: false })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (action === 'clear') {
|
|
38
|
+
perf.clearRecentEntries()
|
|
39
|
+
return NextResponse.json({ cleared: true, enabled: perf.isEnabled() })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return NextResponse.json({ error: 'Invalid action. Use "enable", "disable", or "clear".' }, { status: 400 })
|
|
43
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getPluginManager } from '@/lib/server/plugins'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
|
|
4
5
|
export async function POST(req: Request) {
|
|
5
6
|
const body = await req.json()
|
|
@@ -17,7 +18,7 @@ export async function POST(req: Request) {
|
|
|
17
18
|
return NextResponse.json({ ok: true, dependencyInfo: result })
|
|
18
19
|
} catch (err: unknown) {
|
|
19
20
|
return NextResponse.json(
|
|
20
|
-
{ error:
|
|
21
|
+
{ error: errorMessage(err) },
|
|
21
22
|
{ status: 400 },
|
|
22
23
|
)
|
|
23
24
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getPluginManager, sanitizePluginFilename } from '@/lib/server/plugins'
|
|
3
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
3
4
|
import {
|
|
4
5
|
inferPluginInstallSourceFromUrl,
|
|
5
6
|
inferPluginPublisherSourceFromUrl,
|
|
@@ -57,7 +58,7 @@ export async function POST(req: Request) {
|
|
|
57
58
|
})
|
|
58
59
|
return json({ ok: true, filename: installed.filename, hash: installed.sourceHash }, 200, origin)
|
|
59
60
|
} catch (err: unknown) {
|
|
60
|
-
const msg =
|
|
61
|
+
const msg = errorMessage(err)
|
|
61
62
|
const isTimeout = /abort|timeout/i.test(msg)
|
|
62
63
|
const status = /valid HTTPS URL|Filename|Invalid filename|HTML page|too large/i.test(msg)
|
|
63
64
|
? 400
|
|
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'
|
|
|
2
2
|
import { inferPluginPublisherSourceFromUrl } from '@/lib/plugin-sources'
|
|
3
3
|
import { searchClawHub } from '@/lib/server/clawhub-client'
|
|
4
4
|
import type { PluginCatalogSource } from '@/types'
|
|
5
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
5
6
|
|
|
6
7
|
export const dynamic = 'force-dynamic'
|
|
7
8
|
|
|
@@ -77,7 +78,7 @@ export async function GET(req: Request) {
|
|
|
77
78
|
} catch (err: unknown) {
|
|
78
79
|
console.warn('[marketplace] SC Registry failed:', {
|
|
79
80
|
registryUrl: registry.url,
|
|
80
|
-
error:
|
|
81
|
+
error: errorMessage(err),
|
|
81
82
|
})
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -98,7 +99,7 @@ export async function GET(req: Request) {
|
|
|
98
99
|
catalogSource: 'clawhub',
|
|
99
100
|
})))
|
|
100
101
|
} catch (err: unknown) {
|
|
101
|
-
console.warn('[marketplace] ClawHub failed:',
|
|
102
|
+
console.warn('[marketplace] ClawHub failed:', errorMessage(err))
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
allPlugins.sort((a, b) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getPluginManager } from '@/lib/server/plugins'
|
|
3
3
|
import '@/lib/server/builtin-plugins'
|
|
4
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
4
5
|
|
|
5
6
|
export const dynamic = 'force-dynamic'
|
|
6
7
|
|
|
@@ -33,7 +34,7 @@ export async function PUT(req: Request) {
|
|
|
33
34
|
})
|
|
34
35
|
} catch (err: unknown) {
|
|
35
36
|
return NextResponse.json(
|
|
36
|
-
{ error:
|
|
37
|
+
{ error: errorMessage(err) },
|
|
37
38
|
{ status: 400 },
|
|
38
39
|
)
|
|
39
40
|
}
|
|
@@ -5,6 +5,8 @@ import fs from 'fs'
|
|
|
5
5
|
import path from 'path'
|
|
6
6
|
import { localIP } from '@/lib/server/storage'
|
|
7
7
|
import { resolveDevServerLaunchDir } from '@/lib/server/devserver-launch'
|
|
8
|
+
import { resolvePathWithinBaseDir } from '@/lib/server/path-utils'
|
|
9
|
+
import { hmrSingleton, sleep } from '@/lib/shared-utils'
|
|
8
10
|
|
|
9
11
|
// ---------------------------------------------------------------------------
|
|
10
12
|
// MIME types for static server
|
|
@@ -35,9 +37,8 @@ interface PreviewServer {
|
|
|
35
37
|
log: string
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
?? ((globalThis as unknown as Record<string, unknown>)[globalKey] = new Map<string, PreviewServer>())
|
|
40
|
+
const servers: Map<string, PreviewServer> =
|
|
41
|
+
hmrSingleton('__swarmclaw_preview_servers__', () => new Map<string, PreviewServer>())
|
|
41
42
|
|
|
42
43
|
// ---------------------------------------------------------------------------
|
|
43
44
|
// Helpers
|
|
@@ -134,11 +135,11 @@ function createStaticServer(dir: string): http.Server {
|
|
|
134
135
|
|
|
135
136
|
let reqPath = decodeURIComponent((req.url || '/').split('?')[0])
|
|
136
137
|
if (reqPath === '/') reqPath = '/index.html'
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
const relativeReqPath = reqPath.replace(/^\/+/, '')
|
|
139
|
+
let normalizedFile = ''
|
|
140
|
+
try {
|
|
141
|
+
normalizedFile = resolvePathWithinBaseDir(dir, relativeReqPath)
|
|
142
|
+
} catch {
|
|
142
143
|
res.writeHead(403)
|
|
143
144
|
res.end('Forbidden')
|
|
144
145
|
return
|
|
@@ -147,7 +148,7 @@ function createStaticServer(dir: string): http.Server {
|
|
|
147
148
|
const candidates = [
|
|
148
149
|
normalizedFile,
|
|
149
150
|
normalizedFile + '.html',
|
|
150
|
-
|
|
151
|
+
resolvePathWithinBaseDir(dir, `${relativeReqPath.replace(/\/+$/, '')}/index.html`),
|
|
151
152
|
]
|
|
152
153
|
|
|
153
154
|
for (const candidate of candidates) {
|
|
@@ -241,7 +242,7 @@ async function startNpmServer(dir: string, command: string[], port: number, fram
|
|
|
241
242
|
servers.set(dirKey(dir), entry)
|
|
242
243
|
|
|
243
244
|
// Wait for the server to start and detect the actual port
|
|
244
|
-
await
|
|
245
|
+
await sleep(5000)
|
|
245
246
|
if (proc.exitCode !== null) {
|
|
246
247
|
servers.delete(dirKey(dir))
|
|
247
248
|
throw new Error(`npm dev server exited early with code ${proc.exitCode}\n${log.slice(-4000)}`)
|
|
@@ -50,7 +50,7 @@ export async function DELETE(_req: Request, { params }: { params: Promise<{ id:
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
clearProjectId(loadAgents, saveAgents, 'agents')
|
|
53
|
-
clearProjectId(loadTasks, saveTasks, 'tasks')
|
|
53
|
+
clearProjectId(loadTasks, saveTasks as any, 'tasks')
|
|
54
54
|
clearProjectId(loadSchedules, saveSchedules, 'schedules')
|
|
55
55
|
clearProjectId(loadSkills, saveSkills, 'skills')
|
|
56
56
|
clearProjectId(loadSecrets, saveSecrets, 'secrets')
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import test, { afterEach } from 'node:test'
|
|
3
|
+
|
|
4
|
+
import { DELETE as deleteScheduleRoute, PUT as updateSchedule } from './route'
|
|
5
|
+
import { loadAgents, loadSchedules, saveAgents, saveSchedules } from '@/lib/server/storage'
|
|
6
|
+
|
|
7
|
+
const originalAgents = loadAgents()
|
|
8
|
+
const originalSchedules = loadSchedules()
|
|
9
|
+
|
|
10
|
+
function routeParams(id: string) {
|
|
11
|
+
return { params: Promise.resolve({ id }) }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function seedAgent(id: string, overrides: Record<string, unknown> = {}) {
|
|
15
|
+
const agents = loadAgents()
|
|
16
|
+
const now = Date.now()
|
|
17
|
+
agents[id] = {
|
|
18
|
+
id,
|
|
19
|
+
name: 'Schedule Route Agent',
|
|
20
|
+
description: 'Schedule route test agent',
|
|
21
|
+
systemPrompt: 'Handle schedules.',
|
|
22
|
+
provider: 'openai',
|
|
23
|
+
model: 'gpt-4o-mini',
|
|
24
|
+
credentialId: null,
|
|
25
|
+
fallbackCredentialIds: [],
|
|
26
|
+
apiEndpoint: null,
|
|
27
|
+
plugins: ['manage_schedules'],
|
|
28
|
+
createdAt: now,
|
|
29
|
+
updatedAt: now,
|
|
30
|
+
...overrides,
|
|
31
|
+
}
|
|
32
|
+
saveAgents(agents)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
saveAgents(originalAgents)
|
|
37
|
+
saveSchedules(originalSchedules)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('PUT /api/schedules/[id] pauses equivalent reminder schedules together', async () => {
|
|
41
|
+
seedAgent('schedule-route-agent')
|
|
42
|
+
const now = Date.now()
|
|
43
|
+
saveSchedules({
|
|
44
|
+
one: {
|
|
45
|
+
id: 'one',
|
|
46
|
+
name: 'Iran Update',
|
|
47
|
+
agentId: 'schedule-route-agent',
|
|
48
|
+
taskPrompt: 'Daily check for updates on US-Iran tensions',
|
|
49
|
+
scheduleType: 'cron',
|
|
50
|
+
cron: '0 9 * * *',
|
|
51
|
+
status: 'active',
|
|
52
|
+
createdByAgentId: 'schedule-route-agent',
|
|
53
|
+
createdInSessionId: 'session-reminder',
|
|
54
|
+
createdAt: now,
|
|
55
|
+
updatedAt: now,
|
|
56
|
+
},
|
|
57
|
+
two: {
|
|
58
|
+
id: 'two',
|
|
59
|
+
name: 'Iran Reminder',
|
|
60
|
+
agentId: 'schedule-route-agent',
|
|
61
|
+
taskPrompt: 'Periodic update check for US-Iran tensions',
|
|
62
|
+
scheduleType: 'interval',
|
|
63
|
+
intervalMs: 86_400_000,
|
|
64
|
+
status: 'active',
|
|
65
|
+
createdByAgentId: 'schedule-route-agent',
|
|
66
|
+
createdInSessionId: 'session-reminder',
|
|
67
|
+
createdAt: now + 1,
|
|
68
|
+
updatedAt: now + 1,
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const response = await updateSchedule(new Request('http://local/api/schedules/one', {
|
|
73
|
+
method: 'PUT',
|
|
74
|
+
headers: { 'content-type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ status: 'paused' }),
|
|
76
|
+
}), routeParams('one'))
|
|
77
|
+
|
|
78
|
+
assert.equal(response.status, 200)
|
|
79
|
+
const payload = await response.json() as Record<string, unknown>
|
|
80
|
+
assert.deepEqual(new Set(payload.affectedScheduleIds as string[]), new Set(['one', 'two']))
|
|
81
|
+
|
|
82
|
+
const schedules = loadSchedules()
|
|
83
|
+
assert.equal(schedules.one.status, 'paused')
|
|
84
|
+
assert.equal(schedules.two.status, 'paused')
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('DELETE /api/schedules/[id] deletes equivalent reminder schedules together', async () => {
|
|
88
|
+
seedAgent('schedule-route-agent-delete')
|
|
89
|
+
const now = Date.now()
|
|
90
|
+
saveSchedules({
|
|
91
|
+
one: {
|
|
92
|
+
id: 'one',
|
|
93
|
+
name: 'Iran Update',
|
|
94
|
+
agentId: 'schedule-route-agent-delete',
|
|
95
|
+
taskPrompt: 'Daily check for updates on US-Iran tensions',
|
|
96
|
+
scheduleType: 'cron',
|
|
97
|
+
cron: '0 9 * * *',
|
|
98
|
+
status: 'active',
|
|
99
|
+
createdByAgentId: 'schedule-route-agent-delete',
|
|
100
|
+
createdInSessionId: 'session-reminder',
|
|
101
|
+
createdAt: now,
|
|
102
|
+
updatedAt: now,
|
|
103
|
+
},
|
|
104
|
+
two: {
|
|
105
|
+
id: 'two',
|
|
106
|
+
name: 'Iran Reminder',
|
|
107
|
+
agentId: 'schedule-route-agent-delete',
|
|
108
|
+
taskPrompt: 'Periodic update check for US-Iran tensions',
|
|
109
|
+
scheduleType: 'interval',
|
|
110
|
+
intervalMs: 86_400_000,
|
|
111
|
+
status: 'active',
|
|
112
|
+
createdByAgentId: 'schedule-route-agent-delete',
|
|
113
|
+
createdInSessionId: 'session-reminder',
|
|
114
|
+
createdAt: now + 1,
|
|
115
|
+
updatedAt: now + 1,
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const response = await deleteScheduleRoute(
|
|
120
|
+
new Request('http://local/api/schedules/one', { method: 'DELETE' }),
|
|
121
|
+
routeParams('one'),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
assert.equal(response.status, 200)
|
|
125
|
+
const payload = await response.json() as Record<string, unknown>
|
|
126
|
+
assert.deepEqual(new Set(payload.deletedIds as string[]), new Set(['one', 'two']))
|
|
127
|
+
assert.deepEqual(loadSchedules(), {})
|
|
128
|
+
})
|