@johpaz/hive-agents 0.0.34 → 0.0.36
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 +64 -39
- package/dist/hive.js +4539 -4586
- package/dist/ui/assets/AgentCreateForm-tJZv9FZC.js +1 -0
- package/dist/ui/assets/AgentDetailPage-Du-mRcAX.js +1 -0
- package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +1 -0
- package/dist/ui/assets/{AgentsPage-DhCjvDNa.js → AgentsPage-YvSgWRiw.js} +7 -7
- package/dist/ui/assets/CanvasPage-DtMwGvxf.js +33 -0
- package/dist/ui/assets/ChannelsPage-BdBXWHjj.js +8 -0
- package/dist/ui/assets/DashboardPage-ghl1ZguH.js +6 -0
- package/dist/ui/assets/{LoginPage-B30OrEBy.js → LoginPage-CAmSI9Vy.js} +1 -1
- package/dist/ui/assets/LogsPage-DAPBHkwK.js +1 -0
- package/dist/ui/assets/MeetingPage-WjjGOqqU.js +1 -0
- package/dist/ui/assets/{NotFound-HD1Yp9yK.js → NotFound-BMeQSGcG.js} +1 -1
- package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +1 -0
- package/dist/ui/assets/{RecoverPage-CLF6buGP.js → RecoverPage-DpW3l-yv.js} +1 -1
- package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +9 -0
- package/dist/ui/assets/SetupPage-DKmLVUaj.js +1 -0
- package/dist/ui/assets/{WebChatPage-Um3VANzn.js → WebChatPage-CVRcKept.js} +2 -2
- package/dist/ui/assets/accordion-C5d5Rm5z.js +1 -0
- package/dist/ui/assets/{activity-SfJ6UDF2.js → activity-c3pNngT_.js} +1 -1
- package/dist/ui/assets/alert-C-NE-P3s.js +1 -0
- package/dist/ui/assets/{alert-dialog-M893TdvF.js → alert-dialog-C5mzbHdP.js} +1 -1
- package/dist/ui/assets/arrow-left-CBcbX5EZ.js +1 -0
- package/dist/ui/assets/badge-ChpACfWO.js +1 -0
- package/dist/ui/assets/{calendar-CMMeWsP-.js → calendar-B-KZ9RQO.js} +1 -1
- package/dist/ui/assets/{card-C7P3W6_y.js → card-CNf6BS2e.js} +1 -1
- package/dist/ui/assets/chevron-left-D4U-5A27.js +1 -0
- package/dist/ui/assets/chevron-right-CR4Skrf3.js +1 -0
- package/dist/ui/assets/chevron-up-BYhk0K2J.js +1 -0
- package/dist/ui/assets/{circle-alert-7koABcbO.js → circle-alert-CyHDwUj8.js} +1 -1
- package/dist/ui/assets/circle-check-Bb54Ebmu.js +1 -0
- package/dist/ui/assets/{cpu-mBJgRJzM.js → cpu-Cdgc_B1K.js} +1 -1
- package/dist/ui/assets/dialog-QnZ0ad8O.js +1 -0
- package/dist/ui/assets/{download-oaofq4K1.js → download-C3ifGMjJ.js} +1 -1
- package/dist/ui/assets/dropdown-menu-BK-CO3Od.js +1 -0
- package/dist/ui/assets/{es-eUrU2hyB.js → es-NQNoaWDx.js} +1 -1
- package/dist/ui/assets/{external-link-SkkF2Z7B.js → external-link-BvxYeTP1.js} +1 -1
- package/dist/ui/assets/{eye-B8lq7sWG.js → eye-DqNTU_GD.js} +1 -1
- package/dist/ui/assets/{file-text-0oYol8Bb.js → file-text-BT_9S9SM.js} +1 -1
- package/dist/ui/assets/{folder-open-DVYu2lgk.js → folder-open-BhH8y9ac.js} +1 -1
- package/dist/ui/assets/gauge-D_TMa4i9.js +1 -0
- package/dist/ui/assets/{globe-BVPd5DRa.js → globe-DeCQTCDJ.js} +1 -1
- package/dist/ui/assets/{hexagon-BIAFUAlQ.js → hexagon-DsGOUl-H.js} +1 -1
- package/dist/ui/assets/{history-BUAnaMQo.js → history-BSG-Ypqf.js} +1 -1
- package/dist/ui/assets/index-B2fCYtTS.css +2 -0
- package/dist/ui/assets/index-DMCjjdqf.js +116 -0
- package/dist/ui/assets/{info-DWioleen.js → info-NwLoa2Mj.js} +1 -1
- package/dist/ui/assets/{key-BCGwSKKc.js → key-3EP0dhkT.js} +1 -1
- package/dist/ui/assets/label-D2H1IR_J.js +1 -0
- package/dist/ui/assets/loader-circle-CZNax6kS.js +1 -0
- package/dist/ui/assets/{lock-D7PCO7GC.js → lock-Ei1_J-Nq.js} +1 -1
- package/dist/ui/assets/{pause-CI1JFH6r.js → pause-BUqah9Bi.js} +1 -1
- package/dist/ui/assets/play-NcZ4swwL.js +1 -0
- package/dist/ui/assets/plus-CX1xyhp5.js +1 -0
- package/dist/ui/assets/progress-BherYzY6.js +1 -0
- package/dist/ui/assets/{refresh-cw-BLmKlO4J.js → refresh-cw-DaYdjQFk.js} +1 -1
- package/dist/ui/assets/{save-M1nv6H3P.js → save-CUdYyHNy.js} +1 -1
- package/dist/ui/assets/scroll-area-DkeyX32e.js +1 -0
- package/dist/ui/assets/{send-ijRfR0gp.js → send-B0H5SEIE.js} +1 -1
- package/dist/ui/assets/{settings-BvXhlJCF.js → settings-Ds4SqD8s.js} +1 -1
- package/dist/ui/assets/{slider-DrDFLwXh.js → slider-CsiUDxc3.js} +1 -1
- package/dist/ui/assets/{sparkles-C4MACMbE.js → sparkles-yUEb-7oH.js} +1 -1
- package/dist/ui/assets/{square-D_-gRT1l.js → square-BD81nFtN.js} +1 -1
- package/dist/ui/assets/switch-BDwN8RYV.js +1 -0
- package/dist/ui/assets/{table-DWEJJiuF.js → table-CSc8ubon.js} +1 -1
- package/dist/ui/assets/terminal-DN38Q456.js +1 -0
- package/dist/ui/assets/{textarea-CwPvQVAG.js → textarea-CXgXWKrT.js} +1 -1
- package/dist/ui/assets/{trash-2-Blkv31Dz.js → trash-2-CNjMkoq6.js} +1 -1
- package/dist/ui/assets/{triangle-alert-BKgbd30k.js → triangle-alert-C9Y8Ub4X.js} +1 -1
- package/dist/ui/assets/useProviders-C6_QHsEi.js +1 -0
- package/dist/ui/assets/{vendor-radix-JY4ncZrD.js → vendor-radix-cw1bQaVC.js} +4 -4
- package/dist/ui/assets/{vendor-react-CscwQerf.js → vendor-react-D4s9E-zj.js} +1 -1
- package/dist/ui/assets/{volume-2-BiUgObeI.js → volume-2-CeSXNDv4.js} +1 -1
- package/dist/ui/assets/{zap-CpyuQJEC.js → zap-hlXjpSeA.js} +1 -1
- package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +1 -0
- package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +1 -0
- package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +1 -0
- package/dist/ui/dist/assets/AgentsPage-YvSgWRiw.js +10 -0
- package/dist/ui/dist/assets/CanvasPage-DtMwGvxf.js +33 -0
- package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +8 -0
- package/dist/ui/dist/assets/DashboardPage-ghl1ZguH.js +6 -0
- package/dist/ui/dist/assets/LoginPage-CAmSI9Vy.js +1 -0
- package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +1 -0
- package/dist/ui/dist/assets/MeetingPage-WjjGOqqU.js +1 -0
- package/dist/ui/dist/assets/NotFound-BMeQSGcG.js +1 -0
- package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +1 -0
- package/dist/ui/dist/assets/RecoverPage-DpW3l-yv.js +1 -0
- package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +9 -0
- package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +1 -0
- package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +16 -0
- package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +1 -0
- package/dist/ui/dist/assets/activity-c3pNngT_.js +1 -0
- package/dist/ui/dist/assets/alert-C-NE-P3s.js +1 -0
- package/dist/ui/dist/assets/alert-dialog-C5mzbHdP.js +1 -0
- package/dist/ui/dist/assets/arrow-left-CBcbX5EZ.js +1 -0
- package/dist/ui/dist/assets/badge-ChpACfWO.js +1 -0
- package/dist/ui/dist/assets/calendar-B-KZ9RQO.js +1 -0
- package/dist/ui/dist/assets/card-CNf6BS2e.js +1 -0
- package/dist/ui/dist/assets/chevron-left-D4U-5A27.js +1 -0
- package/dist/ui/dist/assets/chevron-right-CR4Skrf3.js +1 -0
- package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +1 -0
- package/dist/ui/dist/assets/circle-alert-CyHDwUj8.js +1 -0
- package/dist/ui/dist/assets/circle-check-Bb54Ebmu.js +1 -0
- package/dist/ui/dist/assets/cpu-Cdgc_B1K.js +1 -0
- package/dist/ui/dist/assets/dialog-QnZ0ad8O.js +1 -0
- package/dist/ui/dist/assets/download-C3ifGMjJ.js +1 -0
- package/dist/ui/dist/assets/dropdown-menu-BK-CO3Od.js +1 -0
- package/dist/ui/dist/assets/es-NQNoaWDx.js +1 -0
- package/dist/ui/dist/assets/external-link-BvxYeTP1.js +1 -0
- package/dist/ui/dist/assets/eye-DqNTU_GD.js +1 -0
- package/dist/ui/dist/assets/file-text-BT_9S9SM.js +1 -0
- package/dist/ui/dist/assets/folder-open-BhH8y9ac.js +1 -0
- package/dist/ui/dist/assets/format-GVHeOyWI.js +1 -0
- package/dist/ui/dist/assets/gateway-url-COCbW0IR.js +1 -0
- package/dist/ui/dist/assets/gauge-D_TMa4i9.js +1 -0
- package/dist/ui/dist/assets/globe-DeCQTCDJ.js +1 -0
- package/dist/ui/dist/assets/hexagon-DsGOUl-H.js +1 -0
- package/dist/ui/dist/assets/history-BSG-Ypqf.js +1 -0
- package/dist/ui/dist/assets/index-B2fCYtTS.css +2 -0
- package/dist/ui/dist/assets/index-DMCjjdqf.js +116 -0
- package/dist/ui/dist/assets/info-NwLoa2Mj.js +1 -0
- package/dist/ui/dist/assets/key-3EP0dhkT.js +1 -0
- package/dist/ui/dist/assets/label-D2H1IR_J.js +1 -0
- package/dist/ui/dist/assets/loader-circle-CZNax6kS.js +1 -0
- package/dist/ui/dist/assets/lock-Ei1_J-Nq.js +1 -0
- package/dist/ui/dist/assets/pause-BUqah9Bi.js +1 -0
- package/dist/ui/dist/assets/play-NcZ4swwL.js +1 -0
- package/dist/ui/dist/assets/plus-CX1xyhp5.js +1 -0
- package/dist/ui/dist/assets/progress-BherYzY6.js +1 -0
- package/dist/ui/dist/assets/refresh-cw-DaYdjQFk.js +1 -0
- package/dist/ui/dist/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
- package/dist/ui/dist/assets/save-CUdYyHNy.js +1 -0
- package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +1 -0
- package/dist/ui/dist/assets/send-B0H5SEIE.js +1 -0
- package/dist/ui/dist/assets/settings-Ds4SqD8s.js +1 -0
- package/dist/ui/dist/assets/slider-CsiUDxc3.js +14 -0
- package/dist/ui/dist/assets/sparkles-yUEb-7oH.js +1 -0
- package/dist/ui/dist/assets/square-BD81nFtN.js +1 -0
- package/dist/ui/dist/assets/switch-BDwN8RYV.js +1 -0
- package/dist/ui/dist/assets/table-CSc8ubon.js +1 -0
- package/dist/ui/dist/assets/terminal-DN38Q456.js +1 -0
- package/dist/ui/dist/assets/textarea-CXgXWKrT.js +1 -0
- package/dist/ui/dist/assets/trash-2-CNjMkoq6.js +1 -0
- package/dist/ui/dist/assets/triangle-alert-C9Y8Ub4X.js +1 -0
- package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +1 -0
- package/dist/ui/dist/assets/utils-3pnRFmFe.js +1 -0
- package/dist/ui/dist/assets/vendor-charts-Bu2lyBKP.js +65 -0
- package/dist/ui/dist/assets/vendor-query-DsWPbQdG.js +1 -0
- package/dist/ui/dist/assets/vendor-radix-cw1bQaVC.js +63 -0
- package/dist/ui/dist/assets/vendor-react-D4s9E-zj.js +1 -0
- package/dist/ui/dist/assets/vendor-router-C9pIYwbJ.js +3 -0
- package/dist/ui/dist/assets/volume-2-CeSXNDv4.js +1 -0
- package/dist/ui/dist/assets/zap-hlXjpSeA.js +1 -0
- package/dist/ui/dist/favicon.ico +0 -0
- package/dist/ui/dist/index.html +40 -0
- package/dist/ui/dist/placeholder.svg +1 -0
- package/dist/ui/index.html +7 -11
- package/package.json +137 -15
- package/packages/cli/src/adapters/binary.ts +461 -0
- package/packages/cli/src/adapters/bun-global.ts +378 -0
- package/packages/cli/src/adapters/config.ts +314 -0
- package/packages/cli/src/adapters/docker.ts +308 -0
- package/packages/cli/src/adapters/factory.ts +168 -0
- package/packages/cli/src/adapters/index.ts +80 -0
- package/packages/cli/src/adapters/types.ts +218 -0
- package/packages/cli/src/commands/agent-run.ts +168 -0
- package/packages/cli/src/commands/agents.ts +398 -0
- package/packages/cli/src/commands/chat.ts +142 -0
- package/packages/cli/src/commands/config.ts +49 -0
- package/packages/cli/src/commands/cron.ts +487 -0
- package/packages/cli/src/commands/dev.ts +58 -0
- package/packages/cli/src/commands/doctor.ts +320 -0
- package/packages/cli/src/commands/gateway.ts +719 -0
- package/packages/cli/src/commands/logs.ts +57 -0
- package/packages/cli/src/commands/mcp.ts +175 -0
- package/packages/cli/src/commands/message.ts +77 -0
- package/packages/cli/src/commands/migrate.ts +90 -0
- package/packages/cli/src/commands/onboard.ts +1656 -0
- package/packages/cli/src/commands/security.ts +144 -0
- package/packages/cli/src/commands/service.ts +50 -0
- package/packages/cli/src/commands/sessions.ts +116 -0
- package/packages/cli/src/commands/skills.ts +215 -0
- package/packages/cli/src/commands/update.ts +203 -0
- package/packages/cli/src/index.ts +210 -0
- package/packages/cli/src/ui-bundle.generated.ts +3 -0
- package/packages/cli/src/utils/token.ts +6 -0
- package/packages/core/src/agent/agent-loop.ts +691 -0
- package/packages/core/src/agent/compaction.ts +240 -0
- package/packages/core/src/agent/context-compiler.ts +467 -0
- package/packages/core/src/agent/context-guard.ts +91 -0
- package/packages/core/src/agent/conversation-store.ts +244 -0
- package/packages/core/src/agent/curator.ts +158 -0
- package/packages/core/src/agent/hooks.ts +166 -0
- package/packages/core/src/agent/llm-client.ts +167 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +212 -0
- package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
- package/packages/core/src/agent/llm-providers/gemini.ts +215 -0
- package/packages/core/src/agent/llm-providers/groq.ts +5 -0
- package/packages/core/src/agent/llm-providers/interface.ts +195 -0
- package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
- package/packages/core/src/agent/llm-providers/local-llama.ts +37 -0
- package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
- package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
- package/packages/core/src/agent/llm-providers/ollama.ts +175 -0
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +379 -0
- package/packages/core/src/agent/llm-providers/openai.ts +5 -0
- package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
- package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
- package/packages/core/src/agent/native-tools.ts +31 -0
- package/packages/core/src/agent/playbook-selector.ts +147 -0
- package/packages/core/src/agent/prompt-builder.ts +169 -0
- package/packages/core/src/agent/providers/index.ts +204 -0
- package/packages/core/src/agent/providers.ts +1 -0
- package/packages/core/src/agent/reflector.ts +200 -0
- package/packages/core/src/agent/service.ts +267 -0
- package/packages/core/src/agent/skill-selector.ts +479 -0
- package/packages/core/src/agent/stuck-loop.ts +133 -0
- package/packages/core/src/agent/tool-selector.ts +569 -0
- package/packages/core/src/agent/tracer.ts +100 -0
- package/packages/core/src/auth/auth.ts +108 -0
- package/packages/core/src/auth/index.ts +1 -0
- package/packages/core/src/canvas/a2ui-tools.ts +255 -0
- package/packages/core/src/canvas/canvas-manager.ts +390 -0
- package/packages/core/src/canvas/canvas-tools.ts +448 -0
- package/packages/core/src/canvas/emitter.ts +149 -0
- package/packages/core/src/canvas/index.ts +3 -0
- package/packages/core/src/channels/base.ts +154 -0
- package/packages/core/src/channels/discord.ts +273 -0
- package/packages/core/src/channels/index.ts +7 -0
- package/packages/core/src/channels/manager.ts +450 -0
- package/packages/core/src/channels/slack.ts +323 -0
- package/packages/core/src/channels/telegram.ts +612 -0
- package/packages/core/src/channels/webchat.ts +139 -0
- package/packages/core/src/channels/whatsapp.ts +548 -0
- package/packages/core/src/config/index.ts +12 -0
- package/packages/core/src/config/loader.ts +569 -0
- package/packages/core/src/events/agent-bus.ts +460 -0
- package/packages/core/src/events/event-bus.ts +169 -0
- package/packages/core/src/gateway/channel-notify.ts +64 -0
- package/packages/core/src/gateway/helpers/cors.ts +32 -0
- package/packages/core/src/gateway/helpers/index.ts +4 -0
- package/packages/core/src/gateway/helpers/narration.ts +57 -0
- package/packages/core/src/gateway/helpers/path.ts +13 -0
- package/packages/core/src/gateway/helpers/redact.ts +61 -0
- package/packages/core/src/gateway/index.ts +5 -0
- package/packages/core/src/gateway/initializer.ts +363 -0
- package/packages/core/src/gateway/lane-queue.ts +169 -0
- package/packages/core/src/gateway/llm-local/client.ts +94 -0
- package/packages/core/src/gateway/llm-local/detector.ts +321 -0
- package/packages/core/src/gateway/llm-local/downloader.ts +216 -0
- package/packages/core/src/gateway/llm-local/index.ts +34 -0
- package/packages/core/src/gateway/llm-local/manager.ts +186 -0
- package/packages/core/src/gateway/llm-local/models.ts +149 -0
- package/packages/core/src/gateway/llm-local/server.ts +179 -0
- package/packages/core/src/gateway/resolver.ts +108 -0
- package/packages/core/src/gateway/router.ts +124 -0
- package/packages/core/src/gateway/routes/agents.ts +210 -0
- package/packages/core/src/gateway/routes/auth.ts +244 -0
- package/packages/core/src/gateway/routes/channels.ts +484 -0
- package/packages/core/src/gateway/routes/chat.ts +241 -0
- package/packages/core/src/gateway/routes/config.ts +12 -0
- package/packages/core/src/gateway/routes/cron-api.ts +544 -0
- package/packages/core/src/gateway/routes/ethics.ts +46 -0
- package/packages/core/src/gateway/routes/llm-local.ts +271 -0
- package/packages/core/src/gateway/routes/mcp.ts +319 -0
- package/packages/core/src/gateway/routes/meeting.ts +232 -0
- package/packages/core/src/gateway/routes/models.ts +163 -0
- package/packages/core/src/gateway/routes/multimodal.ts +93 -0
- package/packages/core/src/gateway/routes/providers.ts +220 -0
- package/packages/core/src/gateway/routes/setup.ts +441 -0
- package/packages/core/src/gateway/routes/skills.ts +115 -0
- package/packages/core/src/gateway/routes/system.ts +469 -0
- package/packages/core/src/gateway/routes/tasks.ts +44 -0
- package/packages/core/src/gateway/routes/tools.ts +59 -0
- package/packages/core/src/gateway/routes/tts-local.ts +388 -0
- package/packages/core/src/gateway/routes/users.ts +122 -0
- package/packages/core/src/gateway/routes/voice.ts +189 -0
- package/packages/core/src/gateway/routes/workspace.ts +281 -0
- package/packages/core/src/gateway/server.ts +2744 -0
- package/packages/core/src/gateway/session.ts +95 -0
- package/packages/core/src/gateway/slash-commands.ts +207 -0
- package/packages/core/src/gateway/tts/README.md +94 -0
- package/packages/core/src/gateway/tts/package.json +25 -0
- package/packages/core/src/gateway/tts/src/client.ts +59 -0
- package/packages/core/src/gateway/tts/src/detect.ts +42 -0
- package/packages/core/src/gateway/tts/src/index.ts +15 -0
- package/packages/core/src/gateway/tts/src/install.ts +129 -0
- package/packages/core/src/gateway/tts/src/models.ts +50 -0
- package/packages/core/src/gateway/tts/src/server.ts +252 -0
- package/packages/core/src/gateway/tts/voices/.gitkeep +0 -0
- package/packages/core/src/heartbeat/index.ts +157 -0
- package/packages/core/src/index.ts +56 -0
- package/packages/core/src/mcp/hot-reload.ts +148 -0
- package/packages/core/src/mcp/singleton.ts +21 -0
- package/packages/core/src/mcp/tool-sync.ts +176 -0
- package/packages/core/src/multimodal/index.ts +2 -0
- package/packages/core/src/multimodal/types.ts +28 -0
- package/packages/core/src/multimodal/vision-service.ts +283 -0
- package/packages/core/src/plugins/api.ts +128 -0
- package/packages/core/src/plugins/index.ts +2 -0
- package/packages/core/src/plugins/loader.ts +365 -0
- package/packages/core/src/resilience/circuit-breaker.ts +225 -0
- package/packages/core/src/scheduler/CronScheduler.ts +699 -0
- package/packages/core/src/scheduler/dag/AgentExecutor.ts +53 -0
- package/packages/core/src/scheduler/dag/DAGScheduler.ts +250 -0
- package/packages/core/src/scheduler/dag/EventBridge.ts +122 -0
- package/packages/core/src/scheduler/dag/TaskGraph.ts +192 -0
- package/packages/core/src/scheduler/dag/TaskNode.ts +97 -0
- package/packages/core/src/scheduler/dag/TaskResult.ts +22 -0
- package/packages/core/src/scheduler/dag/errors.ts +37 -0
- package/packages/core/src/scheduler/dag/index.ts +26 -0
- package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +97 -0
- package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +21 -0
- package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +46 -0
- package/packages/core/src/scheduler/index.ts +22 -0
- package/packages/core/src/scheduler/integration.ts +237 -0
- package/packages/core/src/scheduler/types.ts +164 -0
- package/packages/core/src/security/google-chat.ts +269 -0
- package/packages/core/src/security/index.ts +192 -0
- package/packages/core/src/security/pairing.ts +250 -0
- package/packages/core/src/security/rate-limit.ts +270 -0
- package/packages/core/src/security/signal.ts +321 -0
- package/packages/core/src/state/store.ts +312 -0
- package/packages/core/src/storage/crypto.ts +197 -0
- package/packages/core/src/storage/migrate.ts +147 -0
- package/packages/core/src/storage/onboarding.ts +1506 -0
- package/packages/core/src/storage/schema.ts +666 -0
- package/packages/core/src/storage/seed.ts +628 -0
- package/packages/core/src/storage/sqlite.ts +407 -0
- package/packages/core/src/storage/usage.ts +374 -0
- package/packages/core/src/tool-runtime/index.ts +476 -0
- package/packages/core/src/tool-runtime/tool-worker.ts +125 -0
- package/packages/core/src/tools/agents/get-available-models.ts +118 -0
- package/packages/core/src/tools/agents/index.ts +610 -0
- package/packages/core/src/tools/canvas/index.ts +420 -0
- package/packages/core/src/tools/cli/index.ts +142 -0
- package/packages/core/src/tools/core/index.ts +478 -0
- package/packages/core/src/tools/cron/index.ts +635 -0
- package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
- package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
- package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
- package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
- package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
- package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
- package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
- package/packages/core/src/tools/filesystem/index.ts +34 -0
- package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
- package/packages/core/src/tools/index.ts +197 -0
- package/packages/core/src/tools/meeting/index.ts +363 -0
- package/packages/core/src/tools/office/index.ts +47 -0
- package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
- package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
- package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
- package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
- package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
- package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
- package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
- package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
- package/packages/core/src/tools/types.ts +39 -0
- package/packages/core/src/tools/voice/index.ts +104 -0
- package/packages/core/src/tools/web/browser-click.ts +78 -0
- package/packages/core/src/tools/web/browser-extract.ts +139 -0
- package/packages/core/src/tools/web/browser-navigate.ts +106 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
- package/packages/core/src/tools/web/browser-script.ts +88 -0
- package/packages/core/src/tools/web/browser-service.ts +554 -0
- package/packages/core/src/tools/web/browser-type.ts +101 -0
- package/packages/core/src/tools/web/browser-wait.ts +136 -0
- package/packages/core/src/tools/web/index.ts +41 -0
- package/packages/core/src/tools/web/web-fetch.ts +78 -0
- package/packages/core/src/tools/web/web-search.ts +123 -0
- package/packages/core/src/utils/benchmark.ts +80 -0
- package/packages/core/src/utils/crypto.ts +73 -0
- package/packages/core/src/utils/date.ts +42 -0
- package/packages/core/src/utils/index.ts +5 -0
- package/packages/core/src/utils/logger.ts +389 -0
- package/packages/core/src/utils/retry.ts +70 -0
- package/packages/core/src/utils/toon.ts +253 -0
- package/packages/core/src/voice/index.ts +643 -0
- package/packages/mcp/src/config.ts +13 -0
- package/packages/mcp/src/index.ts +1 -0
- package/packages/mcp/src/logger.ts +47 -0
- package/packages/mcp/src/manager.ts +439 -0
- package/packages/mcp/src/transports/index.ts +67 -0
- package/packages/mcp/src/transports/sse.ts +238 -0
- package/packages/mcp/src/transports/websocket.ts +159 -0
- package/packages/skills/src/bundled/agents/agent_spawner/SKILL.md +167 -0
- package/packages/skills/src/bundled/agents/code_delegator/SKILL.md +156 -0
- package/packages/skills/src/bundled/agents/memory_manager/SKILL.md +143 -0
- package/packages/skills/src/bundled/agents/research_and_remember/SKILL.md +139 -0
- package/packages/skills/src/bundled/agents/task_orchestrator/SKILL.md +198 -0
- package/packages/skills/src/bundled/canvas/a2ui_dashboard/SKILL.md +176 -0
- package/packages/skills/src/bundled/canvas/a2ui_form/SKILL.md +202 -0
- package/packages/skills/src/bundled/canvas/a2ui_interactive/SKILL.md +206 -0
- package/packages/skills/src/bundled/canvas/canvas_dashboard/SKILL.md +146 -0
- package/packages/skills/src/bundled/canvas/canvas_interact/SKILL.md +148 -0
- package/packages/skills/src/bundled/canvas/canvas_report/SKILL.md +146 -0
- package/packages/skills/src/bundled/cli/cli_pipeline/SKILL.md +136 -0
- package/packages/skills/src/bundled/cli/cli_safe_exec/SKILL.md +125 -0
- package/packages/skills/src/bundled/cron_manager/SKILL.md +188 -0
- package/packages/skills/src/bundled/cron_reminder/SKILL.md +112 -0
- package/packages/skills/src/bundled/filesystem/file_manager/SKILL.md +118 -0
- package/packages/skills/src/bundled/filesystem/file_read_and_summarize/SKILL.md +108 -0
- package/packages/skills/src/bundled/filesystem/file_writer/SKILL.md +135 -0
- package/packages/skills/src/bundled/meeting/meeting_transcription/SKILL.md +213 -0
- package/packages/skills/src/bundled/office/office_document_manager/SKILL.md +262 -0
- package/packages/skills/src/bundled/search_knowledge/busqueda_fts5/SKILL.md +74 -0
- package/packages/skills/src/bundled/voice/voice_assistant/SKILL.md +174 -0
- package/packages/skills/src/bundled/voice/voice_input/SKILL.md +146 -0
- package/packages/skills/src/bundled/voice/voice_output/SKILL.md +151 -0
- package/packages/skills/src/bundled/web/browser_automate/SKILL.md +120 -0
- package/packages/skills/src/bundled/web/browser_scrape/SKILL.md +109 -0
- package/packages/skills/src/bundled/web/web_monitor/SKILL.md +127 -0
- package/packages/skills/src/bundled/web/web_research/SKILL.md +119 -0
- package/packages/skills/src/bundled-data.generated.ts +1964 -0
- package/packages/skills/src/index.ts +1 -0
- package/packages/skills/src/loader.ts +388 -0
- package/dist/ui/assets/AgentCreateForm-DS6yXjGV.js +0 -1
- package/dist/ui/assets/AgentDetailPage-Ud552U7_.js +0 -1
- package/dist/ui/assets/AgentNewPage-DWWs1P7s.js +0 -1
- package/dist/ui/assets/BridgePage-BD93aBKM.js +0 -1
- package/dist/ui/assets/CanvasPage-CM35yj0Q.js +0 -33
- package/dist/ui/assets/ChannelsPage-CtsWtJdc.js +0 -8
- package/dist/ui/assets/DashboardPage-BpiwR5Jg.js +0 -6
- package/dist/ui/assets/LogsPage-DqUsG3MW.js +0 -1
- package/dist/ui/assets/MeetingPage-C5B8-IzE.js +0 -1
- package/dist/ui/assets/ProjectsPage-zic2sjUf.js +0 -1
- package/dist/ui/assets/ProvidersPage-BxyIGKzh.js +0 -1
- package/dist/ui/assets/SettingsPage-CNFm3nun.js +0 -9
- package/dist/ui/assets/SetupPage-RBcjQtv7.js +0 -1
- package/dist/ui/assets/accordion-BEVqJf2A.js +0 -1
- package/dist/ui/assets/alert-BeGcM0nb.js +0 -1
- package/dist/ui/assets/api-q5Ax-vD2.js +0 -63
- package/dist/ui/assets/arrow-left-B_jlw8X_.js +0 -1
- package/dist/ui/assets/badge-pNhtItyt.js +0 -1
- package/dist/ui/assets/chevron-down-B16UVNlu.js +0 -1
- package/dist/ui/assets/chevron-left-_8ly7Fz0.js +0 -1
- package/dist/ui/assets/chevron-right-yzZLjezG.js +0 -1
- package/dist/ui/assets/chevron-up-CxKDQEE5.js +0 -1
- package/dist/ui/assets/circle-CFKiO9Ds.js +0 -1
- package/dist/ui/assets/circle-check-E2u7ZS2r.js +0 -1
- package/dist/ui/assets/circle-minus-1-TZF2pu.js +0 -1
- package/dist/ui/assets/circle-x-Cm3Sr-xb.js +0 -1
- package/dist/ui/assets/dialog-BaJbZsQF.js +0 -1
- package/dist/ui/assets/dist-DB-fE0Co.js +0 -1
- package/dist/ui/assets/dropdown-menu-DJoOchfz.js +0 -1
- package/dist/ui/assets/gauge-BTpFKuAj.js +0 -1
- package/dist/ui/assets/index-BN0875JH.css +0 -2
- package/dist/ui/assets/index-D4pdc0Uw.js +0 -54
- package/dist/ui/assets/label-C6tqnnKd.js +0 -1
- package/dist/ui/assets/loader-circle-CK3qRV3f.js +0 -1
- package/dist/ui/assets/pencil-BF2_XX-i.js +0 -1
- package/dist/ui/assets/play-DidATMfT.js +0 -1
- package/dist/ui/assets/plus-DXm1XDhQ.js +0 -1
- package/dist/ui/assets/progress-B1HC9cB_.js +0 -1
- package/dist/ui/assets/scroll-area-DKNpYkRA.js +0 -1
- package/dist/ui/assets/search-Co6mulZS.js +0 -1
- package/dist/ui/assets/switch-7AuR7x2g.js +0 -1
- package/dist/ui/assets/terminal-CjZu0OZ0.js +0 -1
- package/dist/ui/assets/useProviders-Bxsnav4y.js +0 -1
- package/dist/ui/assets/useWebSocketStore-ZCW_Nt1w.js +0 -1
- package/dist/ui/assets/x-5cXW_1ZS.js +0 -1
- /package/dist/ui/assets/{format-C0EOLKvf.js → format-GVHeOyWI.js} +0 -0
- /package/dist/ui/assets/{gateway-url-OqLaEDK-.js → gateway-url-COCbW0IR.js} +0 -0
- /package/dist/ui/assets/{utils-_qMjiZaF.js → utils-3pnRFmFe.js} +0 -0
- /package/dist/ui/assets/{vendor-router-DhLEd920.js → vendor-router-C9pIYwbJ.js} +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite"
|
|
2
|
+
import { emitCanvas } from "../../canvas/emitter"
|
|
3
|
+
import { syncSkillsToFTS } from "../../agent/skill-selector"
|
|
4
|
+
|
|
5
|
+
export async function handleGetSkills(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
6
|
+
const skills = getDb().query(`
|
|
7
|
+
SELECT id, name, description, category, tools, triggers, preferred_agents, body, version, version_num, active
|
|
8
|
+
FROM skills
|
|
9
|
+
ORDER BY name
|
|
10
|
+
`).all() as Record<string, unknown>[]
|
|
11
|
+
|
|
12
|
+
return addCorsHeaders(Response.json({
|
|
13
|
+
skills: skills.map(s => ({
|
|
14
|
+
id: s.id,
|
|
15
|
+
name: s.name,
|
|
16
|
+
description: s.description,
|
|
17
|
+
category: s.category,
|
|
18
|
+
tools: s.tools,
|
|
19
|
+
triggers: s.triggers,
|
|
20
|
+
preferred_agents: s.preferred_agents,
|
|
21
|
+
body: s.body,
|
|
22
|
+
version: s.version,
|
|
23
|
+
version_num: s.version_num,
|
|
24
|
+
active: s.active === 1,
|
|
25
|
+
}))
|
|
26
|
+
}), req)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function handleActivateSkill(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
30
|
+
const url = new URL(req.url)
|
|
31
|
+
const parts = url.pathname.split("/").filter(Boolean)
|
|
32
|
+
// /api/skills/:id/toggle → parts[2] = id
|
|
33
|
+
const skillId = parts[2]
|
|
34
|
+
const body = await req.json().catch(() => ({}))
|
|
35
|
+
const { active } = body
|
|
36
|
+
|
|
37
|
+
if (!skillId) {
|
|
38
|
+
return addCorsHeaders(Response.json({ success: false, error: "skillId required" }), req)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getDb().query(`UPDATE skills SET active = ? WHERE id = ?`).run(active ? 1 : 0, skillId)
|
|
42
|
+
|
|
43
|
+
// Re-sync FTS5 index so semantic matching respects the new active state immediately
|
|
44
|
+
syncSkillsToFTS().catch(() => {})
|
|
45
|
+
|
|
46
|
+
return addCorsHeaders(Response.json({ success: true, skillId, active }), req)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function handleUpdateSkill(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
50
|
+
const url = new URL(req.url)
|
|
51
|
+
const parts = url.pathname.split("/").filter(Boolean)
|
|
52
|
+
const skillId = parts[2]
|
|
53
|
+
const body = await req.json().catch(() => ({}))
|
|
54
|
+
|
|
55
|
+
if (!skillId) {
|
|
56
|
+
return addCorsHeaders(Response.json({ success: false, error: "skillId required" }), req)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const updates: string[] = []
|
|
60
|
+
const params: unknown[] = []
|
|
61
|
+
|
|
62
|
+
if (body.name !== undefined) { updates.push("name = ?"); params.push(body.name) }
|
|
63
|
+
if (body.description !== undefined) { updates.push("description = ?"); params.push(body.description) }
|
|
64
|
+
if (body.category !== undefined) { updates.push("category = ?"); params.push(body.category) }
|
|
65
|
+
if (body.tools !== undefined) { updates.push("tools = ?"); params.push(body.tools) }
|
|
66
|
+
if (body.triggers !== undefined) { updates.push("triggers = ?"); params.push(body.triggers) }
|
|
67
|
+
if (body.preferred_agents !== undefined) { updates.push("preferred_agents = ?"); params.push(typeof body.preferred_agents === 'object' ? JSON.stringify(body.preferred_agents) : body.preferred_agents) }
|
|
68
|
+
if (body.body !== undefined) { updates.push("body = ?"); params.push(body.body) }
|
|
69
|
+
if (body.version !== undefined) { updates.push("version = ?"); params.push(body.version) }
|
|
70
|
+
if (body.active !== undefined) { updates.push("active = ?"); params.push(body.active ? 1 : 0) }
|
|
71
|
+
|
|
72
|
+
if (updates.length > 0) {
|
|
73
|
+
updates.push("updated_at = datetime('now')")
|
|
74
|
+
params.push(skillId)
|
|
75
|
+
getDb().query(`UPDATE skills SET ${updates.join(", ")} WHERE id = ?`).run(...params as any[])
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return addCorsHeaders(Response.json({ success: true }), req)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function handleDeleteSkill(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
82
|
+
const url = new URL(req.url)
|
|
83
|
+
const skillId = url.pathname.split("/").pop()
|
|
84
|
+
|
|
85
|
+
if (!skillId) {
|
|
86
|
+
return addCorsHeaders(Response.json({ success: false, error: "skillId required" }), req)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getDb().query(`DELETE FROM skills WHERE id = ?`).run(skillId)
|
|
90
|
+
|
|
91
|
+
return addCorsHeaders(Response.json({ success: true }), req)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function handleCreateSkill(
|
|
95
|
+
req: Request,
|
|
96
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
97
|
+
): Promise<Response> {
|
|
98
|
+
const body = await req.json().catch(() => ({}));
|
|
99
|
+
const { name, description, category, tools, triggers, preferred_agents, body: bodyContent } = body;
|
|
100
|
+
|
|
101
|
+
if (!name) {
|
|
102
|
+
return addCorsHeaders(new Response("Missing name", { status: 400 }), req);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const { randomUUID } = await import("crypto");
|
|
106
|
+
const id = randomUUID();
|
|
107
|
+
|
|
108
|
+
getDb().query(
|
|
109
|
+
`INSERT INTO skills(id, name, description, category, tools, triggers, preferred_agents, body, version, version_num, active) VALUES(?, ?, ?, ?, ?, ?, ?, ?, '0.0.1', 1, 1)`
|
|
110
|
+
).run(id, name, description || "", category || "", tools || "", triggers || "",
|
|
111
|
+
typeof preferred_agents === 'object' ? JSON.stringify(preferred_agents || []) : (preferred_agents || "[]"),
|
|
112
|
+
bodyContent || "");
|
|
113
|
+
|
|
114
|
+
return addCorsHeaders(Response.json({ success: true, id }), req);
|
|
115
|
+
}
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite.ts"
|
|
2
|
+
import { loadConfig } from "../../config/loader.ts"
|
|
3
|
+
import { cpus } from "node:os"
|
|
4
|
+
import { readFile } from "node:fs/promises"
|
|
5
|
+
import { join } from "node:path"
|
|
6
|
+
import pkg from "../../../../../package.json"
|
|
7
|
+
|
|
8
|
+
const CURRENT_VERSION = pkg.version
|
|
9
|
+
|
|
10
|
+
export interface VersionInfo {
|
|
11
|
+
current: string
|
|
12
|
+
latest?: string
|
|
13
|
+
status: "up-to-date" | "update-available" | "checking" | "error"
|
|
14
|
+
error?: string
|
|
15
|
+
installationType?: "docker" | "binary" | "npm" | "bun"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Detecta el tipo de instalación de Hive
|
|
20
|
+
*/
|
|
21
|
+
function detectInstallationType(): "docker" | "binary" | "npm" | "bun" {
|
|
22
|
+
// Docker: existe el archivo .dockerenv o el path contiene /.docker
|
|
23
|
+
if (process.env.HIVE_DOCKER === "true" || process.env.RUNNING_IN_DOCKER === "true") {
|
|
24
|
+
return "docker"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Verificar si hay archivo .dockerenv (solo Linux)
|
|
28
|
+
try {
|
|
29
|
+
if (require("fs").existsSync("/.dockerenv")) {
|
|
30
|
+
return "docker"
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// Ignorar error en sistemas que no soportan require
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Bun: process.execPath contiene "bun"
|
|
37
|
+
if (process.execPath?.includes("bun")) {
|
|
38
|
+
return "bun"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// npm: las variables de entorno de npm
|
|
42
|
+
if (process.env.npm_config_global_prefix) {
|
|
43
|
+
return "npm"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Por defecto, asumir binario standalone
|
|
47
|
+
return "binary"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Obtiene la versión más reciente desde npm registry
|
|
52
|
+
*/
|
|
53
|
+
async function getLatestVersionFromNpm(): Promise<string | null> {
|
|
54
|
+
try {
|
|
55
|
+
const controller = new AbortController()
|
|
56
|
+
const timeout = setTimeout(() => controller.abort(), 5000)
|
|
57
|
+
|
|
58
|
+
const response = await fetch("https://registry.npmjs.org/@johpaz/hive-agents/latest", {
|
|
59
|
+
signal: controller.signal,
|
|
60
|
+
headers: { "Accept": "application/json" }
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
clearTimeout(timeout)
|
|
64
|
+
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const data = await response.json()
|
|
70
|
+
return data.version
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error("[Version] Error fetching from npm:", (error as Error).message)
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Obtiene la versión más reciente desde GitHub Releases
|
|
79
|
+
*/
|
|
80
|
+
async function getLatestVersionFromGitHub(): Promise<string | null> {
|
|
81
|
+
try {
|
|
82
|
+
const controller = new AbortController()
|
|
83
|
+
const timeout = setTimeout(() => controller.abort(), 5000)
|
|
84
|
+
|
|
85
|
+
const response = await fetch("https://api.github.com/repos/johpaz/hive/releases/latest", {
|
|
86
|
+
signal: controller.signal,
|
|
87
|
+
headers: {
|
|
88
|
+
"Accept": "application/vnd.github.v3+json",
|
|
89
|
+
"User-Agent": "Hive-Version-Checker"
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
clearTimeout(timeout)
|
|
94
|
+
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const data = await response.json()
|
|
100
|
+
// Remover prefijo "v" si existe (ej: "v1.7.15" -> "1.7.15")
|
|
101
|
+
return data.tag_name?.replace(/^v/, "") || null
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error("[Version] Error fetching from GitHub:", (error as Error).message)
|
|
104
|
+
return null
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Compara dos versiones semánticas
|
|
110
|
+
* Retorna: 1 si v1 > v2, -1 si v1 < v2, 0 si son iguales
|
|
111
|
+
*/
|
|
112
|
+
function compareVersions(v1: string, v2: string): number {
|
|
113
|
+
const parts1 = v1.split(".").map(Number)
|
|
114
|
+
const parts2 = v2.split(".").map(Number)
|
|
115
|
+
|
|
116
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
117
|
+
const n1 = parts1[i] || 0
|
|
118
|
+
const n2 = parts2[i] || 0
|
|
119
|
+
|
|
120
|
+
if (n1 > n2) return 1
|
|
121
|
+
if (n1 < n2) return -1
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return 0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Handler para obtener información de versión
|
|
129
|
+
*/
|
|
130
|
+
export async function handleGetVersion(
|
|
131
|
+
req: Request,
|
|
132
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
133
|
+
): Promise<Response> {
|
|
134
|
+
const installationType = detectInstallationType()
|
|
135
|
+
|
|
136
|
+
// Responder inmediatamente con la versión actual y estado "checking"
|
|
137
|
+
let versionInfo: VersionInfo = {
|
|
138
|
+
current: CURRENT_VERSION,
|
|
139
|
+
status: "checking",
|
|
140
|
+
installationType
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Siempre verificar en npm registry (es donde se publica @johpaz/hive-agents)
|
|
144
|
+
// GitHub Releases solo como fallback si npm falla
|
|
145
|
+
const latest = await getLatestVersionFromNpm()
|
|
146
|
+
.then(v => v ?? getLatestVersionFromGitHub())
|
|
147
|
+
|
|
148
|
+
if (latest) {
|
|
149
|
+
const isUpdateAvailable = compareVersions(latest, CURRENT_VERSION) > 0
|
|
150
|
+
versionInfo = {
|
|
151
|
+
current: CURRENT_VERSION,
|
|
152
|
+
latest,
|
|
153
|
+
status: isUpdateAvailable ? "update-available" : "up-to-date",
|
|
154
|
+
installationType
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
versionInfo = {
|
|
158
|
+
current: CURRENT_VERSION,
|
|
159
|
+
status: "error",
|
|
160
|
+
error: "No se pudo verificar la última versión. Verifica tu conexión a internet.",
|
|
161
|
+
installationType
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return addCorsHeaders(Response.json(versionInfo), req)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Handler para triggerar una actualización
|
|
170
|
+
*/
|
|
171
|
+
export async function handleTriggerUpdate(
|
|
172
|
+
req: Request,
|
|
173
|
+
addCorsHeaders: (r: Response, req: Request) => Response
|
|
174
|
+
): Promise<Response> {
|
|
175
|
+
const installationType = detectInstallationType()
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
let command: string[]
|
|
179
|
+
let message: string
|
|
180
|
+
|
|
181
|
+
switch (installationType) {
|
|
182
|
+
case "docker":
|
|
183
|
+
// Docker: el usuario debe ejecutar docker compose pull && docker compose up -d
|
|
184
|
+
return addCorsHeaders(Response.json({
|
|
185
|
+
success: false,
|
|
186
|
+
error: "En Docker, ejecuta manualmente: docker compose pull && docker compose up -d",
|
|
187
|
+
instructions: [
|
|
188
|
+
"1. Abre una terminal en el directorio de Hive",
|
|
189
|
+
"2. Ejecuta: docker compose pull",
|
|
190
|
+
"3. Luego ejecuta: docker compose up -d",
|
|
191
|
+
"4. Recarga esta página para ver la nueva versión"
|
|
192
|
+
]
|
|
193
|
+
}), req)
|
|
194
|
+
|
|
195
|
+
case "bun":
|
|
196
|
+
command = ["bun", "install", "-g", "@johpaz/hive-agents@latest"]
|
|
197
|
+
message = "Actualizando Hive desde npm..."
|
|
198
|
+
break
|
|
199
|
+
|
|
200
|
+
case "npm":
|
|
201
|
+
command = ["npm", "install", "-g", "@johpaz/hive-agents@latest"]
|
|
202
|
+
message = "Actualizando Hive desde npm..."
|
|
203
|
+
break
|
|
204
|
+
|
|
205
|
+
case "binary":
|
|
206
|
+
return addCorsHeaders(Response.json({
|
|
207
|
+
success: false,
|
|
208
|
+
error: "Para actualizar el binario, descarga la última versión desde https://github.com/johpaz/hive/releases/latest",
|
|
209
|
+
instructions: [
|
|
210
|
+
"1. Visita https://github.com/johpaz/hive/releases/latest",
|
|
211
|
+
"2. Descarga el binario para tu sistema operativo",
|
|
212
|
+
"3. Reemplaza el archivo existente",
|
|
213
|
+
"4. Ejecuta: hive start"
|
|
214
|
+
]
|
|
215
|
+
}), req)
|
|
216
|
+
|
|
217
|
+
default:
|
|
218
|
+
return addCorsHeaders(Response.json({
|
|
219
|
+
success: false,
|
|
220
|
+
error: "Tipo de instalación no reconocido"
|
|
221
|
+
}), req)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Ejecutar comando de actualización
|
|
225
|
+
const proc = Bun.spawn(command, {
|
|
226
|
+
stdout: "pipe",
|
|
227
|
+
stderr: "pipe",
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
231
|
+
new Response(proc.stdout).text(),
|
|
232
|
+
new Response(proc.stderr).text(),
|
|
233
|
+
proc.exited
|
|
234
|
+
])
|
|
235
|
+
|
|
236
|
+
if (exitCode === 0) {
|
|
237
|
+
return addCorsHeaders(Response.json({
|
|
238
|
+
success: true,
|
|
239
|
+
message: "Hive actualizado correctamente. Reinicia el gateway para aplicar los cambios.",
|
|
240
|
+
output: stdout || stderr,
|
|
241
|
+
instructions: [
|
|
242
|
+
"1. Ejecuta: hive stop",
|
|
243
|
+
"2. Luego ejecuta: hive start",
|
|
244
|
+
"3. Recarga esta página para ver la nueva versión"
|
|
245
|
+
]
|
|
246
|
+
}), req)
|
|
247
|
+
} else {
|
|
248
|
+
return addCorsHeaders(Response.json({
|
|
249
|
+
success: false,
|
|
250
|
+
error: "Error durante la actualización",
|
|
251
|
+
output: stderr || stdout
|
|
252
|
+
}), req)
|
|
253
|
+
}
|
|
254
|
+
} catch (error) {
|
|
255
|
+
return addCorsHeaders(Response.json({
|
|
256
|
+
success: false,
|
|
257
|
+
error: (error as Error).message
|
|
258
|
+
}), req)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function getSystemStats(startTime: number) {
|
|
263
|
+
const mem = process.memoryUsage()
|
|
264
|
+
const uptimeSeconds = Math.floor((Date.now() - startTime) / 1000)
|
|
265
|
+
const uptimeStr = new Date(uptimeSeconds * 1000).toISOString().substr(11, 8)
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
cpu: 0, // Placeholder - Node.js doesn't provide per-process CPU
|
|
269
|
+
memory: {
|
|
270
|
+
rss: Math.round(mem.rss / 1024 / 1024), // MB
|
|
271
|
+
heapUsed: Math.round(mem.heapUsed / 1024 / 1024), // MB
|
|
272
|
+
heapTotal: Math.round(mem.heapTotal / 1024 / 1024), // MB
|
|
273
|
+
heapPercent: Math.round((mem.heapUsed / mem.heapTotal) * 100 * 100) / 100,
|
|
274
|
+
external: Math.round((mem.external || 0) / 1024 / 1024), // MB
|
|
275
|
+
},
|
|
276
|
+
uptime: uptimeStr,
|
|
277
|
+
connections: 0, // Placeholder
|
|
278
|
+
cores: cpus().length,
|
|
279
|
+
recentMessages: 0, // Placeholder
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export async function handleGetActivityStats(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
284
|
+
const db = getDb()
|
|
285
|
+
const url = new URL(req.url)
|
|
286
|
+
const hours = parseInt(url.searchParams.get("hours") || "12", 10)
|
|
287
|
+
|
|
288
|
+
// Get message counts per hour from conversations table
|
|
289
|
+
const now = Date.now()
|
|
290
|
+
const startTime = now - (hours * 60 * 60 * 1000)
|
|
291
|
+
|
|
292
|
+
const rows = db.query(`
|
|
293
|
+
SELECT
|
|
294
|
+
strftime('%Y-%m-%d %H:00', datetime(created_at, 'unixepoch')) as hour,
|
|
295
|
+
COUNT(*) as count
|
|
296
|
+
FROM conversations
|
|
297
|
+
WHERE created_at >= ?
|
|
298
|
+
GROUP BY hour
|
|
299
|
+
ORDER BY hour
|
|
300
|
+
`).all(startTime / 1000) as { hour: string; count: number }[]
|
|
301
|
+
|
|
302
|
+
// Format as array expected by frontend
|
|
303
|
+
const activityData = rows.map(r => ({
|
|
304
|
+
time: r.hour,
|
|
305
|
+
count: r.count,
|
|
306
|
+
}))
|
|
307
|
+
|
|
308
|
+
return addCorsHeaders(Response.json(activityData), req)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export async function handleGetSystemStats(req: Request, addCorsHeaders: (r: Response, req: Request) => Response, startTime: number): Promise<Response> {
|
|
312
|
+
return addCorsHeaders(Response.json(getSystemStats(startTime)), req)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export async function handleGetUsageStats(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
316
|
+
const db = getDb()
|
|
317
|
+
|
|
318
|
+
// Get hours parameter from URL (default to 24 hours)
|
|
319
|
+
const url = new URL(req.url)
|
|
320
|
+
const hours = parseInt(url.searchParams.get("hours") || "24", 10)
|
|
321
|
+
const since = Math.floor(Date.now() / 1000) - (hours * 3600)
|
|
322
|
+
|
|
323
|
+
// Get totals from usage_records table (excluding TOON records)
|
|
324
|
+
const totals = db.query(`
|
|
325
|
+
SELECT
|
|
326
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
327
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
328
|
+
COALESCE(SUM(cost_usd), 0) as costUsd
|
|
329
|
+
FROM usage_records
|
|
330
|
+
WHERE created_at >= ? AND provider != 'toon'
|
|
331
|
+
`).get(since) as { inputTokens: number; outputTokens: number; costUsd: number }
|
|
332
|
+
|
|
333
|
+
// Get TOON savings separately
|
|
334
|
+
const toonTotals = db.query(`
|
|
335
|
+
SELECT
|
|
336
|
+
COALESCE(SUM(toon_saved_tokens), 0) as toonSavedTokens,
|
|
337
|
+
COALESCE(SUM(toon_saved_cost), 0) as toonSavedCost,
|
|
338
|
+
COALESCE(SUM(toon_saved_bytes), 0) as toonSavedBytes,
|
|
339
|
+
COALESCE(AVG(toon_saved_percent), 0) as toonSavedPercent,
|
|
340
|
+
COALESCE(SUM(toon_json_tokens), 0) as toonJsonTokens,
|
|
341
|
+
COALESCE(SUM(toon_toon_tokens), 0) as toonToonTokens,
|
|
342
|
+
COALESCE(SUM(toon_json_bytes), 0) as toonJsonBytes,
|
|
343
|
+
COALESCE(AVG(toon_saved_tokens_pct), 0) as toonSavedTokensPct
|
|
344
|
+
FROM usage_records
|
|
345
|
+
WHERE created_at >= ? AND provider = 'toon'
|
|
346
|
+
`).get(since) as {
|
|
347
|
+
toonSavedTokens: number;
|
|
348
|
+
toonSavedCost: number;
|
|
349
|
+
toonSavedBytes: number;
|
|
350
|
+
toonSavedPercent: number;
|
|
351
|
+
toonJsonTokens: number;
|
|
352
|
+
toonToonTokens: number;
|
|
353
|
+
toonJsonBytes: number;
|
|
354
|
+
toonSavedTokensPct: number;
|
|
355
|
+
}
|
|
356
|
+
const byProviderRows = db.query(`
|
|
357
|
+
SELECT
|
|
358
|
+
provider,
|
|
359
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
360
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
361
|
+
COALESCE(SUM(cost_usd), 0) as costUsd
|
|
362
|
+
FROM usage_records
|
|
363
|
+
WHERE created_at >= ? AND provider != 'toon'
|
|
364
|
+
GROUP BY provider
|
|
365
|
+
`).all(since) as { provider: string; inputTokens: number; outputTokens: number; costUsd: number }[]
|
|
366
|
+
|
|
367
|
+
// Get by model
|
|
368
|
+
const byModelRows = db.query(`
|
|
369
|
+
SELECT
|
|
370
|
+
model,
|
|
371
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
372
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
373
|
+
COALESCE(SUM(cost_usd), 0) as costUsd
|
|
374
|
+
FROM usage_records
|
|
375
|
+
WHERE created_at >= ? AND provider != 'toon'
|
|
376
|
+
GROUP BY model
|
|
377
|
+
`).all(since) as { model: string; inputTokens: number; outputTokens: number; costUsd: number }[]
|
|
378
|
+
|
|
379
|
+
const totalTokens = (totals.inputTokens || 0) + (totals.outputTokens || 0)
|
|
380
|
+
const totalCostUsd = totals.costUsd || 0
|
|
381
|
+
|
|
382
|
+
// Use TOON totals directly from DB - no calculations needed
|
|
383
|
+
const toonSavedTokens = toonTotals?.toonSavedTokens || 0
|
|
384
|
+
const toonSavedCost = toonTotals?.toonSavedCost || 0
|
|
385
|
+
const toonSavedBytes = toonTotals?.toonSavedBytes || 0
|
|
386
|
+
const toonJsonBytes = toonTotals?.toonJsonBytes || 0
|
|
387
|
+
const toonJsonTokens = toonTotals?.toonJsonTokens || 0
|
|
388
|
+
const toonToonTokens = toonTotals?.toonToonTokens || 0
|
|
389
|
+
|
|
390
|
+
// Use saved_percent directly from DB (calculated at record time by toon-format-parser)
|
|
391
|
+
const toonSavedBytesPercent = toonTotals?.toonSavedPercent || 0
|
|
392
|
+
|
|
393
|
+
// Use saved_tokens_pct directly from DB (calculated at record time by toon-format-parser)
|
|
394
|
+
const toonSavingsPercent = toonTotals?.toonSavedTokensPct || 0
|
|
395
|
+
|
|
396
|
+
const stats: UsageStats = {
|
|
397
|
+
totalTokens,
|
|
398
|
+
totalInputTokens: totals.inputTokens || 0,
|
|
399
|
+
totalOutputTokens: totals.outputTokens || 0,
|
|
400
|
+
totalCostUsd,
|
|
401
|
+
toonSavedTokens,
|
|
402
|
+
toonSavedCost,
|
|
403
|
+
toonSavedBytes,
|
|
404
|
+
toonSavedBytesPercent,
|
|
405
|
+
toonJsonTokens,
|
|
406
|
+
toonToonTokens,
|
|
407
|
+
toonSavingsPercent,
|
|
408
|
+
byProvider: Object.fromEntries(
|
|
409
|
+
byProviderRows.map(r => [r.provider, {
|
|
410
|
+
tokens: (r.inputTokens || 0) + (r.outputTokens || 0),
|
|
411
|
+
costUsd: r.costUsd || 0,
|
|
412
|
+
inputTokens: r.inputTokens || 0,
|
|
413
|
+
outputTokens: r.outputTokens || 0,
|
|
414
|
+
}])
|
|
415
|
+
),
|
|
416
|
+
byModel: Object.fromEntries(
|
|
417
|
+
byModelRows.map(r => [r.model, {
|
|
418
|
+
tokens: (r.inputTokens || 0) + (r.outputTokens || 0),
|
|
419
|
+
costUsd: r.costUsd || 0,
|
|
420
|
+
provider: "unknown",
|
|
421
|
+
inputTokens: r.inputTokens || 0,
|
|
422
|
+
outputTokens: r.outputTokens || 0,
|
|
423
|
+
}])
|
|
424
|
+
),
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return addCorsHeaders(Response.json(stats), req)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Add UsageStats interface for backend
|
|
431
|
+
interface UsageStats {
|
|
432
|
+
totalTokens: number;
|
|
433
|
+
totalInputTokens: number;
|
|
434
|
+
totalOutputTokens: number;
|
|
435
|
+
totalCostUsd: number;
|
|
436
|
+
toonSavedTokens: number;
|
|
437
|
+
toonSavedCost: number;
|
|
438
|
+
toonSavedBytes: number;
|
|
439
|
+
toonSavedBytesPercent: number;
|
|
440
|
+
toonJsonTokens: number;
|
|
441
|
+
toonToonTokens: number;
|
|
442
|
+
toonSavingsPercent: number;
|
|
443
|
+
byProvider: Record<string, { tokens: number; costUsd: number; inputTokens: number; outputTokens: number }>;
|
|
444
|
+
byModel: Record<string, { tokens: number; costUsd: number; provider: string; inputTokens: number; outputTokens: number }>;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export async function handleSystemReload(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
448
|
+
return addCorsHeaders(Response.json({ success: true, message: "Reload triggered" }), req)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export async function handleApiReload(
|
|
452
|
+
req: Request,
|
|
453
|
+
addCorsHeaders: (r: Response, req: Request) => Response,
|
|
454
|
+
agent?: any
|
|
455
|
+
): Promise<Response> {
|
|
456
|
+
try {
|
|
457
|
+
const newConfig = await loadConfig()
|
|
458
|
+
if (agent) {
|
|
459
|
+
await agent.updateConfig(newConfig)
|
|
460
|
+
await agent.reload()
|
|
461
|
+
}
|
|
462
|
+
return addCorsHeaders(Response.json({ success: true, message: "Configuration reloaded" }), req)
|
|
463
|
+
} catch (error) {
|
|
464
|
+
return addCorsHeaders(Response.json(
|
|
465
|
+
{ success: false, error: (error as Error).message },
|
|
466
|
+
{ status: 500 }
|
|
467
|
+
), req)
|
|
468
|
+
}
|
|
469
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite"
|
|
2
|
+
|
|
3
|
+
export async function handleGetTasks(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
4
|
+
const url = new URL(req.url)
|
|
5
|
+
const agentId = url.searchParams.get("agentId")
|
|
6
|
+
|
|
7
|
+
let tasks
|
|
8
|
+
if (agentId) {
|
|
9
|
+
tasks = getDb().query("SELECT * FROM tasks WHERE agent_id = ? ORDER BY id ASC").all(agentId)
|
|
10
|
+
} else {
|
|
11
|
+
tasks = getDb().query("SELECT * FROM tasks ORDER BY id ASC").all()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return addCorsHeaders(Response.json({ tasks }), req)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function handleUpdateTask(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
18
|
+
const url = new URL(req.url)
|
|
19
|
+
const taskId = url.pathname.split("/").pop()
|
|
20
|
+
const body = await req.json().catch(() => ({}))
|
|
21
|
+
|
|
22
|
+
if (!taskId) {
|
|
23
|
+
return addCorsHeaders(new Response("Missing ID", { status: 400 }), req)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const updates: string[] = []
|
|
27
|
+
const params: unknown[] = []
|
|
28
|
+
|
|
29
|
+
if (body.status !== undefined) {
|
|
30
|
+
updates.push("status = ?")
|
|
31
|
+
params.push(body.status)
|
|
32
|
+
}
|
|
33
|
+
if (body.result !== undefined) {
|
|
34
|
+
updates.push("result = ?")
|
|
35
|
+
params.push(body.result)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (updates.length > 0) {
|
|
39
|
+
params.push(taskId)
|
|
40
|
+
getDb().query(`UPDATE tasks SET ${updates.join(", ")} WHERE id = ?`).run(...params as any[])
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return addCorsHeaders(Response.json({ ok: true }), req)
|
|
44
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getDb } from "../../storage/sqlite"
|
|
2
|
+
|
|
3
|
+
export async function handleGetTools(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
4
|
+
const tools = getDb().query(`
|
|
5
|
+
SELECT id, name, description, category, active, enabled
|
|
6
|
+
FROM tools
|
|
7
|
+
ORDER BY name
|
|
8
|
+
`).all() as Record<string, unknown>[]
|
|
9
|
+
|
|
10
|
+
return addCorsHeaders(Response.json({
|
|
11
|
+
tools: tools.map(t => ({
|
|
12
|
+
id: t.id,
|
|
13
|
+
name: t.name,
|
|
14
|
+
description: t.description,
|
|
15
|
+
category: t.category,
|
|
16
|
+
active: t.active === 1,
|
|
17
|
+
enabled: t.enabled === 1,
|
|
18
|
+
}))
|
|
19
|
+
}), req)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function handleActivateTool(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
23
|
+
const url = new URL(req.url)
|
|
24
|
+
const toolId = url.pathname.split("/")[3]
|
|
25
|
+
const body = await req.json().catch(() => ({}))
|
|
26
|
+
const { active } = body
|
|
27
|
+
|
|
28
|
+
if (!toolId) {
|
|
29
|
+
return addCorsHeaders(Response.json({ success: false, error: "toolId required" }), req)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getDb().query(`UPDATE tools SET active = ?, enabled = ? WHERE id = ?`).run(active ? 1 : 0, active ? 1 : 0, toolId)
|
|
33
|
+
|
|
34
|
+
return addCorsHeaders(Response.json({ success: true, toolId, active }), req)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function handleUpdateTool(req: Request, addCorsHeaders: (r: Response, req: Request) => Response): Promise<Response> {
|
|
38
|
+
const url = new URL(req.url)
|
|
39
|
+
const toolId = url.pathname.split("/")[3]
|
|
40
|
+
const body = await req.json().catch(() => ({}))
|
|
41
|
+
|
|
42
|
+
if (!toolId) {
|
|
43
|
+
return addCorsHeaders(Response.json({ success: false, error: "toolId required" }), req)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const updates: string[] = []
|
|
47
|
+
const params: unknown[] = []
|
|
48
|
+
|
|
49
|
+
if (body.name !== undefined) { updates.push("name = ?"); params.push(body.name) }
|
|
50
|
+
if (body.description !== undefined) { updates.push("description = ?"); params.push(body.description) }
|
|
51
|
+
if (body.category !== undefined) { updates.push("category = ?"); params.push(body.category) }
|
|
52
|
+
|
|
53
|
+
if (updates.length > 0) {
|
|
54
|
+
params.push(toolId)
|
|
55
|
+
getDb().query(`UPDATE tools SET ${updates.join(", ")} WHERE id = ?`).run(...params as any[])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return addCorsHeaders(Response.json({ success: true }), req)
|
|
59
|
+
}
|