@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.
Files changed (394) hide show
  1. package/README.md +9 -9
  2. package/bin/swarmclaw.js +5 -1
  3. package/bin/worker-cmd.js +73 -0
  4. package/package.json +2 -1
  5. package/src/app/api/agents/[id]/route.ts +17 -7
  6. package/src/app/api/agents/route.ts +21 -8
  7. package/src/app/api/approvals/route.test.ts +6 -6
  8. package/src/app/api/approvals/route.ts +2 -1
  9. package/src/app/api/auth/route.ts +2 -3
  10. package/src/app/api/chatrooms/[id]/chat/route.test.ts +299 -0
  11. package/src/app/api/chatrooms/[id]/chat/route.ts +3 -2
  12. package/src/app/api/chatrooms/[id]/route.ts +7 -6
  13. package/src/app/api/chats/[id]/chat/route.test.ts +496 -0
  14. package/src/app/api/chats/[id]/chat/route.ts +7 -3
  15. package/src/app/api/chats/[id]/clear/route.ts +9 -9
  16. package/src/app/api/chats/[id]/devserver/route.ts +2 -1
  17. package/src/app/api/chats/[id]/edit-resend/route.ts +3 -4
  18. package/src/app/api/chats/[id]/fork/route.ts +3 -5
  19. package/src/app/api/chats/[id]/restore/route.ts +6 -7
  20. package/src/app/api/chats/[id]/retry/route.ts +3 -4
  21. package/src/app/api/chats/[id]/route.ts +61 -62
  22. package/src/app/api/chats/route.ts +7 -1
  23. package/src/app/api/connectors/[id]/route.ts +7 -8
  24. package/src/app/api/connectors/route.ts +5 -4
  25. package/src/app/api/eval/run/route.ts +2 -1
  26. package/src/app/api/eval/suite/route.ts +2 -1
  27. package/src/app/api/external-agents/route.test.ts +1 -1
  28. package/src/app/api/external-agents/route.ts +2 -2
  29. package/src/app/api/files/serve/route.ts +1 -1
  30. package/src/app/api/gateways/[id]/route.ts +7 -5
  31. package/src/app/api/gateways/route.ts +1 -1
  32. package/src/app/api/knowledge/upload/route.ts +1 -1
  33. package/src/app/api/logs/route.ts +5 -7
  34. package/src/app/api/memory-images/[filename]/route.ts +2 -3
  35. package/src/app/api/openclaw/agent-files/route.ts +4 -3
  36. package/src/app/api/openclaw/approvals/route.ts +3 -4
  37. package/src/app/api/openclaw/config-sync/route.ts +3 -2
  38. package/src/app/api/openclaw/cron/route.ts +3 -2
  39. package/src/app/api/openclaw/dotenv-keys/route.ts +2 -1
  40. package/src/app/api/openclaw/exec-config/route.ts +3 -2
  41. package/src/app/api/openclaw/gateway/route.ts +5 -4
  42. package/src/app/api/openclaw/history/route.ts +3 -2
  43. package/src/app/api/openclaw/media/route.ts +2 -1
  44. package/src/app/api/openclaw/permissions/route.ts +3 -2
  45. package/src/app/api/openclaw/sandbox-env/route.ts +3 -2
  46. package/src/app/api/openclaw/skills/install/route.ts +2 -1
  47. package/src/app/api/openclaw/skills/remove/route.ts +2 -1
  48. package/src/app/api/openclaw/skills/route.ts +3 -2
  49. package/src/app/api/orchestrator/run/route.ts +5 -14
  50. package/src/app/api/perf/route.ts +43 -0
  51. package/src/app/api/plugins/dependencies/route.ts +2 -1
  52. package/src/app/api/plugins/install/route.ts +2 -1
  53. package/src/app/api/plugins/marketplace/route.ts +3 -2
  54. package/src/app/api/plugins/settings/route.ts +2 -1
  55. package/src/app/api/preview-server/route.ts +11 -10
  56. package/src/app/api/projects/[id]/route.ts +1 -1
  57. package/src/app/api/schedules/[id]/route.test.ts +128 -0
  58. package/src/app/api/schedules/[id]/route.ts +43 -43
  59. package/src/app/api/schedules/[id]/run/route.ts +11 -62
  60. package/src/app/api/schedules/route.ts +21 -87
  61. package/src/app/api/settings/route.ts +2 -0
  62. package/src/app/api/setup/doctor/route.ts +9 -8
  63. package/src/app/api/tasks/[id]/approve/route.ts +33 -30
  64. package/src/app/api/tasks/[id]/route.ts +12 -35
  65. package/src/app/api/tasks/import/github/route.ts +2 -1
  66. package/src/app/api/tasks/route.ts +79 -91
  67. package/src/app/api/wallets/[id]/approve/route.ts +2 -1
  68. package/src/app/api/wallets/[id]/route.ts +13 -19
  69. package/src/app/api/wallets/[id]/send/route.ts +2 -1
  70. package/src/app/api/wallets/route.ts +2 -1
  71. package/src/app/api/webhooks/[id]/route.ts +2 -1
  72. package/src/app/api/webhooks/route.test.ts +3 -1
  73. package/src/app/page.tsx +23 -331
  74. package/src/cli/index.js +19 -0
  75. package/src/cli/index.ts +38 -7
  76. package/src/cli/spec.js +9 -0
  77. package/src/components/activity/activity-feed.tsx +7 -4
  78. package/src/components/agents/agent-card.tsx +32 -6
  79. package/src/components/agents/agent-chat-list.tsx +55 -22
  80. package/src/components/agents/agent-files-editor.tsx +3 -2
  81. package/src/components/agents/agent-sheet.tsx +123 -22
  82. package/src/components/agents/inspector-panel.tsx +1 -1
  83. package/src/components/agents/openclaw-skills-panel.tsx +2 -1
  84. package/src/components/agents/trash-list.tsx +1 -1
  85. package/src/components/auth/access-key-gate.tsx +8 -2
  86. package/src/components/auth/setup-wizard.tsx +10 -9
  87. package/src/components/auth/user-picker.tsx +3 -2
  88. package/src/components/chat/chat-area.tsx +20 -1
  89. package/src/components/chat/chat-card.tsx +18 -3
  90. package/src/components/chat/chat-header.tsx +24 -4
  91. package/src/components/chat/chat-list.tsx +2 -11
  92. package/src/components/chat/heartbeat-history-panel.tsx +2 -1
  93. package/src/components/chat/message-bubble.tsx +45 -6
  94. package/src/components/chat/message-list.tsx +280 -145
  95. package/src/components/chat/streaming-bubble.tsx +217 -60
  96. package/src/components/chat/swarm-panel.test.ts +274 -0
  97. package/src/components/chat/swarm-panel.tsx +410 -0
  98. package/src/components/chat/swarm-status-card.tsx +346 -0
  99. package/src/components/chat/tool-call-bubble.tsx +48 -23
  100. package/src/components/chatrooms/chatroom-list.tsx +8 -5
  101. package/src/components/chatrooms/chatroom-message.tsx +10 -7
  102. package/src/components/chatrooms/chatroom-view.tsx +12 -9
  103. package/src/components/connectors/connector-health.tsx +6 -4
  104. package/src/components/connectors/connector-list.tsx +16 -11
  105. package/src/components/connectors/connector-sheet.tsx +12 -6
  106. package/src/components/home/home-view.tsx +38 -24
  107. package/src/components/input/chat-input.tsx +10 -1
  108. package/src/components/layout/app-layout.tsx +2 -38
  109. package/src/components/layout/sheet-layer.tsx +50 -0
  110. package/src/components/mcp-servers/mcp-server-list.tsx +37 -5
  111. package/src/components/mcp-servers/mcp-server-sheet.tsx +12 -2
  112. package/src/components/plugins/plugin-list.tsx +8 -4
  113. package/src/components/plugins/plugin-sheet.tsx +2 -1
  114. package/src/components/providers/provider-list.tsx +3 -2
  115. package/src/components/providers/provider-sheet.tsx +2 -1
  116. package/src/components/runs/run-list.tsx +11 -7
  117. package/src/components/schedules/schedule-card.tsx +5 -3
  118. package/src/components/shared/agent-switch-dialog.tsx +1 -1
  119. package/src/components/shared/attachment-chip.tsx +19 -3
  120. package/src/components/shared/notification-center.tsx +6 -3
  121. package/src/components/shared/settings/plugin-manager.tsx +3 -2
  122. package/src/components/shared/settings/section-embedding.tsx +2 -1
  123. package/src/components/shared/settings/section-orchestrator.tsx +2 -1
  124. package/src/components/shared/settings/section-user-preferences.tsx +107 -0
  125. package/src/components/shared/settings/settings-page.tsx +13 -9
  126. package/src/components/skills/clawhub-browser.tsx +15 -4
  127. package/src/components/skills/skill-list.tsx +15 -4
  128. package/src/components/tasks/approvals-panel.tsx +2 -1
  129. package/src/components/tasks/task-board.tsx +35 -37
  130. package/src/components/tasks/task-sheet.tsx +4 -3
  131. package/src/components/ui/full-screen-loader.tsx +164 -0
  132. package/src/components/wallets/wallet-approval-dialog.tsx +2 -1
  133. package/src/components/wallets/wallet-panel.tsx +6 -5
  134. package/src/components/wallets/wallet-section.tsx +3 -2
  135. package/src/components/webhooks/webhook-list.tsx +4 -5
  136. package/src/components/webhooks/webhook-sheet.tsx +6 -6
  137. package/src/hooks/use-app-bootstrap.ts +202 -0
  138. package/src/hooks/use-mounted-ref.ts +14 -0
  139. package/src/hooks/use-now.ts +31 -0
  140. package/src/hooks/use-openclaw-gateway.ts +2 -1
  141. package/src/instrumentation.ts +20 -8
  142. package/src/lib/agent-default-tools.test.ts +52 -0
  143. package/src/lib/agent-default-tools.ts +40 -0
  144. package/src/lib/api-client.test.ts +21 -0
  145. package/src/lib/api-client.ts +6 -11
  146. package/src/lib/canvas-content.test.ts +360 -0
  147. package/src/lib/chat-streaming-state.test.ts +49 -2
  148. package/src/lib/chat-streaming-state.ts +26 -10
  149. package/src/lib/fetch-timeout.test.ts +54 -0
  150. package/src/lib/fetch-timeout.ts +60 -3
  151. package/src/lib/live-tool-events.test.ts +77 -0
  152. package/src/lib/live-tool-events.ts +73 -0
  153. package/src/lib/local-observability.test.ts +2 -2
  154. package/src/lib/openclaw-endpoint.test.ts +1 -1
  155. package/src/lib/providers/anthropic.ts +12 -16
  156. package/src/lib/providers/index.ts +4 -2
  157. package/src/lib/providers/ollama.ts +9 -6
  158. package/src/lib/providers/openai.ts +11 -14
  159. package/src/lib/runtime-env.test.ts +8 -8
  160. package/src/lib/schedule-dedupe-advanced.test.ts +2 -2
  161. package/src/lib/schedule-dedupe.test.ts +1 -1
  162. package/src/lib/schedule-dedupe.ts +3 -2
  163. package/src/lib/server/agent-thread-session.test.ts +6 -6
  164. package/src/lib/server/agent-thread-session.ts +6 -9
  165. package/src/lib/server/alert-dispatch.ts +2 -1
  166. package/src/lib/server/api-routes.test.ts +6 -6
  167. package/src/lib/server/approval-connector-notify.test.ts +4 -4
  168. package/src/lib/server/approvals-auto-approve.test.ts +29 -29
  169. package/src/lib/server/approvals.test.ts +317 -0
  170. package/src/lib/server/approvals.ts +5 -4
  171. package/src/lib/server/autonomy-runtime.test.ts +11 -11
  172. package/src/lib/server/browser-state.ts +2 -2
  173. package/src/lib/server/capability-router.test.ts +1 -1
  174. package/src/lib/server/capability-router.ts +3 -2
  175. package/src/lib/server/chat-execution-advanced.test.ts +15 -2
  176. package/src/lib/server/chat-execution-connector-delivery.ts +67 -0
  177. package/src/lib/server/chat-execution-disabled.test.ts +3 -3
  178. package/src/lib/server/chat-execution-eval-history.test.ts +3 -3
  179. package/src/lib/server/chat-execution-heartbeat.test.ts +42 -1
  180. package/src/lib/server/chat-execution-session-sync.test.ts +119 -0
  181. package/src/lib/server/chat-execution-tool-events.ts +116 -0
  182. package/src/lib/server/chat-execution-utils.test.ts +479 -0
  183. package/src/lib/server/chat-execution-utils.ts +533 -0
  184. package/src/lib/server/chat-execution.ts +153 -748
  185. package/src/lib/server/chat-streaming-utils.ts +174 -0
  186. package/src/lib/server/chat-turn-tool-routing.ts +310 -0
  187. package/src/lib/server/chatroom-session-persistence.test.ts +2 -2
  188. package/src/lib/server/clawhub-client.ts +2 -1
  189. package/src/lib/server/collection-helpers.test.ts +92 -0
  190. package/src/lib/server/collection-helpers.ts +25 -3
  191. package/src/lib/server/connectors/access.ts +146 -0
  192. package/src/lib/server/connectors/bluebubbles.test.ts +1 -1
  193. package/src/lib/server/connectors/bluebubbles.ts +4 -4
  194. package/src/lib/server/connectors/commands.ts +367 -0
  195. package/src/lib/server/connectors/connector-routing.test.ts +4 -4
  196. package/src/lib/server/connectors/delivery.ts +142 -0
  197. package/src/lib/server/connectors/discord.ts +37 -40
  198. package/src/lib/server/connectors/email.ts +11 -10
  199. package/src/lib/server/connectors/googlechat.ts +4 -4
  200. package/src/lib/server/connectors/inbound-audio-transcription.ts +2 -1
  201. package/src/lib/server/connectors/ingress-delivery.ts +23 -0
  202. package/src/lib/server/connectors/manager-roundtrip.test.ts +300 -0
  203. package/src/lib/server/connectors/manager.test.ts +352 -77
  204. package/src/lib/server/connectors/manager.ts +134 -673
  205. package/src/lib/server/connectors/matrix.ts +4 -4
  206. package/src/lib/server/connectors/message-sentinel.ts +7 -0
  207. package/src/lib/server/connectors/openclaw.test.ts +1 -1
  208. package/src/lib/server/connectors/openclaw.ts +8 -10
  209. package/src/lib/server/connectors/outbox.test.ts +192 -0
  210. package/src/lib/server/connectors/outbox.ts +369 -0
  211. package/src/lib/server/connectors/pairing.test.ts +18 -1
  212. package/src/lib/server/connectors/pairing.ts +49 -4
  213. package/src/lib/server/connectors/policy.ts +9 -3
  214. package/src/lib/server/connectors/reconnect-state.ts +71 -0
  215. package/src/lib/server/connectors/response-media.ts +256 -0
  216. package/src/lib/server/connectors/runtime-state.ts +67 -0
  217. package/src/lib/server/connectors/session.test.ts +357 -0
  218. package/src/lib/server/connectors/session.ts +422 -0
  219. package/src/lib/server/connectors/signal.ts +7 -7
  220. package/src/lib/server/connectors/slack.ts +43 -43
  221. package/src/lib/server/connectors/teams.ts +4 -4
  222. package/src/lib/server/connectors/telegram.ts +37 -43
  223. package/src/lib/server/connectors/types.ts +31 -1
  224. package/src/lib/server/connectors/whatsapp.test.ts +108 -0
  225. package/src/lib/server/connectors/whatsapp.ts +106 -34
  226. package/src/lib/server/context-manager.test.ts +409 -0
  227. package/src/lib/server/cost.test.ts +1 -1
  228. package/src/lib/server/daemon-policy.ts +78 -0
  229. package/src/lib/server/daemon-state-connectors.test.ts +167 -0
  230. package/src/lib/server/daemon-state.test.ts +283 -55
  231. package/src/lib/server/daemon-state.ts +106 -109
  232. package/src/lib/server/data-dir.test.ts +5 -5
  233. package/src/lib/server/data-dir.ts +4 -0
  234. package/src/lib/server/delegation-jobs-advanced.test.ts +1 -1
  235. package/src/lib/server/delegation-jobs.test.ts +87 -0
  236. package/src/lib/server/delegation-jobs.ts +42 -48
  237. package/src/lib/server/devserver-launch.ts +1 -1
  238. package/src/lib/server/document-utils.ts +7 -9
  239. package/src/lib/server/elevenlabs.ts +2 -1
  240. package/src/lib/server/embeddings.test.ts +105 -0
  241. package/src/lib/server/ethereum.ts +3 -2
  242. package/src/lib/server/eval/agent-regression.ts +3 -2
  243. package/src/lib/server/eval/runner.ts +2 -1
  244. package/src/lib/server/eval/scorer.ts +2 -1
  245. package/src/lib/server/evm-swap.ts +2 -1
  246. package/src/lib/server/gateway/protocol.test.ts +1 -1
  247. package/src/lib/server/guardian.ts +2 -1
  248. package/src/lib/server/heartbeat-blocked-suppression.test.ts +151 -0
  249. package/src/lib/server/heartbeat-service-timer.test.ts +6 -6
  250. package/src/lib/server/heartbeat-service.test.ts +406 -0
  251. package/src/lib/server/heartbeat-service.ts +54 -7
  252. package/src/lib/server/heartbeat-wake.test.ts +19 -0
  253. package/src/lib/server/heartbeat-wake.ts +17 -16
  254. package/src/lib/server/integrity-monitor.test.ts +149 -0
  255. package/src/lib/server/json-utils.ts +22 -0
  256. package/src/lib/server/knowledge-db.test.ts +13 -13
  257. package/src/lib/server/link-understanding.ts +2 -1
  258. package/src/lib/server/llm-response-cache.test.ts +1 -1
  259. package/src/lib/server/main-agent-loop-advanced.test.ts +65 -3
  260. package/src/lib/server/main-agent-loop.test.ts +6 -6
  261. package/src/lib/server/main-agent-loop.ts +21 -7
  262. package/src/lib/server/mcp-client.test.ts +1 -1
  263. package/src/lib/server/mcp-conformance.test.ts +1 -1
  264. package/src/lib/server/mcp-conformance.ts +3 -2
  265. package/src/lib/server/memory-consolidation.ts +2 -1
  266. package/src/lib/server/memory-db.test.ts +485 -0
  267. package/src/lib/server/memory-db.ts +39 -26
  268. package/src/lib/server/memory-graph.test.ts +2 -2
  269. package/src/lib/server/memory-policy.test.ts +7 -7
  270. package/src/lib/server/memory-retrieval.test.ts +1 -1
  271. package/src/lib/server/openclaw-config-sync.ts +2 -1
  272. package/src/lib/server/openclaw-deploy.test.ts +1 -1
  273. package/src/lib/server/openclaw-deploy.ts +8 -12
  274. package/src/lib/server/openclaw-exec-config.ts +2 -1
  275. package/src/lib/server/openclaw-gateway.ts +6 -7
  276. package/src/lib/server/openclaw-skills-normalize.ts +2 -1
  277. package/src/lib/server/openclaw-sync.ts +7 -5
  278. package/src/lib/server/orchestrator-lg-structure.test.ts +17 -0
  279. package/src/lib/server/orchestrator-lg.ts +199 -327
  280. package/src/lib/server/path-utils.ts +31 -0
  281. package/src/lib/server/perf.ts +161 -0
  282. package/src/lib/server/plugins-approval-guidance.ts +115 -0
  283. package/src/lib/server/plugins.test.ts +1 -1
  284. package/src/lib/server/plugins.ts +22 -132
  285. package/src/lib/server/process-manager.ts +5 -8
  286. package/src/lib/server/provider-health.test.ts +137 -0
  287. package/src/lib/server/provider-health.ts +3 -3
  288. package/src/lib/server/provider-model-discovery.ts +3 -12
  289. package/src/lib/server/queue-followups.test.ts +9 -9
  290. package/src/lib/server/queue-reconcile.test.ts +2 -2
  291. package/src/lib/server/queue-recovery.test.ts +269 -0
  292. package/src/lib/server/queue.test.ts +570 -0
  293. package/src/lib/server/queue.ts +62 -455
  294. package/src/lib/server/resolve-image.ts +30 -0
  295. package/src/lib/server/runtime-settings.test.ts +4 -4
  296. package/src/lib/server/runtime-storage-write-paths.test.ts +60 -0
  297. package/src/lib/server/schedule-normalization.test.ts +279 -0
  298. package/src/lib/server/schedule-service.ts +263 -0
  299. package/src/lib/server/scheduler.ts +17 -74
  300. package/src/lib/server/session-mailbox.test.ts +191 -0
  301. package/src/lib/server/session-run-manager.test.ts +640 -0
  302. package/src/lib/server/session-run-manager.ts +59 -15
  303. package/src/lib/server/session-tools/autonomy-tools.test.ts +20 -20
  304. package/src/lib/server/session-tools/calendar.ts +2 -1
  305. package/src/lib/server/session-tools/canvas.ts +2 -1
  306. package/src/lib/server/session-tools/chatroom.ts +2 -1
  307. package/src/lib/server/session-tools/connector.ts +26 -28
  308. package/src/lib/server/session-tools/context-mgmt.ts +3 -2
  309. package/src/lib/server/session-tools/crawl.ts +4 -3
  310. package/src/lib/server/session-tools/crud.ts +105 -324
  311. package/src/lib/server/session-tools/delegate-fallback.test.ts +9 -9
  312. package/src/lib/server/session-tools/delegate.ts +6 -8
  313. package/src/lib/server/session-tools/discovery-approvals.test.ts +15 -15
  314. package/src/lib/server/session-tools/discovery.ts +4 -3
  315. package/src/lib/server/session-tools/document.ts +2 -1
  316. package/src/lib/server/session-tools/email.ts +2 -1
  317. package/src/lib/server/session-tools/extract.ts +2 -1
  318. package/src/lib/server/session-tools/file.ts +4 -3
  319. package/src/lib/server/session-tools/http.ts +2 -1
  320. package/src/lib/server/session-tools/human-loop.ts +2 -1
  321. package/src/lib/server/session-tools/image-gen.ts +4 -3
  322. package/src/lib/server/session-tools/index.ts +26 -30
  323. package/src/lib/server/session-tools/mailbox.ts +2 -1
  324. package/src/lib/server/session-tools/manage-connectors.test.ts +4 -4
  325. package/src/lib/server/session-tools/manage-schedules.test.ts +12 -12
  326. package/src/lib/server/session-tools/manage-tasks-advanced.test.ts +5 -5
  327. package/src/lib/server/session-tools/manage-tasks.test.ts +2 -2
  328. package/src/lib/server/session-tools/monitor.ts +2 -1
  329. package/src/lib/server/session-tools/platform.ts +2 -1
  330. package/src/lib/server/session-tools/plugin-creator.ts +2 -1
  331. package/src/lib/server/session-tools/replicate.ts +3 -2
  332. package/src/lib/server/session-tools/session-tools-wiring.test.ts +6 -6
  333. package/src/lib/server/session-tools/shell.ts +4 -9
  334. package/src/lib/server/session-tools/subagent.ts +322 -170
  335. package/src/lib/server/session-tools/table.ts +6 -5
  336. package/src/lib/server/session-tools/wallet-tool.test.ts +3 -3
  337. package/src/lib/server/session-tools/wallet.ts +7 -6
  338. package/src/lib/server/session-tools/web-browser-config.test.ts +1 -0
  339. package/src/lib/server/session-tools/web-utils.ts +317 -0
  340. package/src/lib/server/session-tools/web.ts +62 -328
  341. package/src/lib/server/skill-prompt-budget.test.ts +1 -1
  342. package/src/lib/server/skills-normalize.ts +2 -1
  343. package/src/lib/server/storage-item-access.test.ts +302 -0
  344. package/src/lib/server/storage.ts +366 -314
  345. package/src/lib/server/stream-agent-chat.test.ts +82 -3
  346. package/src/lib/server/stream-agent-chat.ts +146 -510
  347. package/src/lib/server/stream-continuation.ts +412 -0
  348. package/src/lib/server/subagent-lineage.test.ts +647 -0
  349. package/src/lib/server/subagent-lineage.ts +435 -0
  350. package/src/lib/server/subagent-runtime.test.ts +484 -0
  351. package/src/lib/server/subagent-runtime.ts +419 -0
  352. package/src/lib/server/subagent-swarm.test.ts +391 -0
  353. package/src/lib/server/subagent-swarm.ts +564 -0
  354. package/src/lib/server/system-events.ts +3 -3
  355. package/src/lib/server/task-followups.test.ts +491 -0
  356. package/src/lib/server/task-followups.ts +391 -0
  357. package/src/lib/server/task-lifecycle.test.ts +205 -0
  358. package/src/lib/server/task-lifecycle.ts +200 -0
  359. package/src/lib/server/task-quality-gate.test.ts +1 -1
  360. package/src/lib/server/task-resume.ts +208 -0
  361. package/src/lib/server/task-service.test.ts +108 -0
  362. package/src/lib/server/task-service.ts +264 -0
  363. package/src/lib/server/task-validation.test.ts +1 -1
  364. package/src/lib/server/test-utils/run-with-temp-data-dir.ts +42 -0
  365. package/src/lib/server/tool-capability-policy.test.ts +2 -2
  366. package/src/lib/server/tool-capability-policy.ts +3 -2
  367. package/src/lib/server/tool-planning.ts +2 -1
  368. package/src/lib/server/tool-retry.ts +2 -3
  369. package/src/lib/server/wake-dispatcher.test.ts +303 -0
  370. package/src/lib/server/wake-dispatcher.ts +318 -0
  371. package/src/lib/server/wake-mode.test.ts +161 -0
  372. package/src/lib/server/wake-mode.ts +174 -0
  373. package/src/lib/server/wallet-service.ts +8 -9
  374. package/src/lib/server/watch-jobs.ts +2 -1
  375. package/src/lib/server/workspace-context.ts +2 -2
  376. package/src/lib/shared-utils.test.ts +142 -0
  377. package/src/lib/shared-utils.ts +62 -0
  378. package/src/lib/tool-event-summary.ts +2 -1
  379. package/src/lib/view-routes.test.ts +100 -0
  380. package/src/lib/wallet.test.ts +322 -6
  381. package/src/proxy.test.ts +4 -4
  382. package/src/proxy.ts +2 -3
  383. package/src/stores/set-if-changed.ts +40 -0
  384. package/src/stores/slices/agent-slice.ts +111 -0
  385. package/src/stores/slices/auth-slice.ts +25 -0
  386. package/src/stores/slices/data-slice.ts +301 -0
  387. package/src/stores/slices/index.ts +7 -0
  388. package/src/stores/slices/session-slice.ts +112 -0
  389. package/src/stores/slices/task-slice.ts +63 -0
  390. package/src/stores/slices/ui-slice.ts +192 -0
  391. package/src/stores/use-app-store.ts +17 -822
  392. package/src/stores/use-approval-store.ts +2 -1
  393. package/src/stores/use-chat-store.ts +8 -1
  394. package/src/types/index.ts +10 -0
@@ -0,0 +1,301 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AppState } from '../use-app-store'
3
+ import type { NetworkInfo, Directory, ProviderInfo, Credentials, Schedule, AppSettings, OrchestratorSecret, ProviderConfig, Skill, Connector, Webhook, McpServerConfig, PluginMeta, Project, ActivityEntry, AppNotification, ApprovalRequest, GatewayProfile } from '../../types'
4
+ import { fetchDirs, fetchProviders, fetchCredentials } from '../../lib/chats'
5
+ import { fetchSchedules } from '../../lib/schedules'
6
+ import { api } from '../../lib/api-client'
7
+ import { safeStorageGetJson, safeStorageSet } from '../../lib/safe-storage'
8
+ import { setIfChanged } from '../set-if-changed'
9
+
10
+ export interface DataSlice {
11
+ networkInfo: NetworkInfo | null
12
+ loadNetworkInfo: () => Promise<void>
13
+ dirs: Directory[]
14
+ loadDirs: () => Promise<void>
15
+ providers: ProviderInfo[]
16
+ credentials: Credentials
17
+ loadProviders: () => Promise<void>
18
+ loadCredentials: () => Promise<void>
19
+ schedules: Record<string, Schedule>
20
+ loadSchedules: () => Promise<void>
21
+ appSettings: AppSettings
22
+ loadSettings: () => Promise<void>
23
+ updateSettings: (patch: Partial<AppSettings>) => Promise<void>
24
+ secrets: Record<string, OrchestratorSecret>
25
+ loadSecrets: () => Promise<void>
26
+ providerConfigs: ProviderConfig[]
27
+ loadProviderConfigs: () => Promise<void>
28
+ gatewayProfiles: GatewayProfile[]
29
+ loadGatewayProfiles: () => Promise<void>
30
+ skills: Record<string, Skill>
31
+ loadSkills: () => Promise<void>
32
+ connectors: Record<string, Connector>
33
+ loadConnectors: () => Promise<void>
34
+ webhooks: Record<string, Webhook>
35
+ loadWebhooks: () => Promise<void>
36
+ mcpServers: Record<string, McpServerConfig>
37
+ loadMcpServers: () => Promise<void>
38
+ plugins: Record<string, PluginMeta>
39
+ loadPlugins: () => Promise<void>
40
+ projects: Record<string, Project>
41
+ loadProjects: () => Promise<void>
42
+ activityEntries: ActivityEntry[]
43
+ loadActivity: (filters?: { entityType?: string; limit?: number }) => Promise<void>
44
+ lastReadTimestamps: Record<string, number>
45
+ markChatRead: (id: string) => void
46
+ approvals: Record<string, ApprovalRequest>
47
+ loadApprovals: () => Promise<void>
48
+ submitApprovalDecision: (id: string, approved: boolean) => Promise<void>
49
+ notifications: AppNotification[]
50
+ unreadNotificationCount: number
51
+ loadNotifications: () => Promise<void>
52
+ markNotificationRead: (id: string) => Promise<void>
53
+ markAllNotificationsRead: () => Promise<void>
54
+ clearReadNotifications: () => Promise<void>
55
+ }
56
+
57
+ export const createDataSlice: StateCreator<AppState, [], [], DataSlice> = (set, get) => ({
58
+ networkInfo: null,
59
+ loadNetworkInfo: async () => {
60
+ try {
61
+ const info = await api<NetworkInfo>('GET', '/ip')
62
+ setIfChanged<AppState>(set, 'networkInfo', info)
63
+ } catch (err) {
64
+ console.warn('Store error:', err)
65
+ setIfChanged<AppState>(set, 'networkInfo', null)
66
+ }
67
+ },
68
+ dirs: [],
69
+ loadDirs: async () => {
70
+ try {
71
+ const dirs = await fetchDirs()
72
+ setIfChanged<AppState>(set, 'dirs', dirs)
73
+ } catch {
74
+ setIfChanged<AppState>(set, 'dirs', [])
75
+ }
76
+ },
77
+ providers: [],
78
+ credentials: {},
79
+ loadProviders: async () => {
80
+ try {
81
+ const providers = await fetchProviders()
82
+ setIfChanged<AppState>(set, 'providers', providers)
83
+ } catch (err) {
84
+ console.warn('Store error:', err)
85
+ setIfChanged<AppState>(set, 'providers', [])
86
+ }
87
+ },
88
+ loadCredentials: async () => {
89
+ try {
90
+ const credentials = await fetchCredentials()
91
+ setIfChanged<AppState>(set, 'credentials', credentials)
92
+ } catch (err) {
93
+ console.warn('Store error:', err)
94
+ setIfChanged<AppState>(set, 'credentials', {})
95
+ }
96
+ },
97
+ schedules: {},
98
+ loadSchedules: async () => {
99
+ try {
100
+ const schedules = await fetchSchedules()
101
+ setIfChanged<AppState>(set, 'schedules', schedules)
102
+ } catch (err) {
103
+ console.warn('Store error:', err)
104
+ setIfChanged<AppState>(set, 'schedules', {})
105
+ }
106
+ },
107
+ appSettings: {},
108
+ loadSettings: async () => {
109
+ try {
110
+ const settings = await api<AppSettings>('GET', '/settings')
111
+ setIfChanged<AppState>(set, 'appSettings', settings)
112
+ } catch (err) {
113
+ console.warn('Store error:', err)
114
+ setIfChanged<AppState>(set, 'appSettings', {})
115
+ }
116
+ },
117
+ updateSettings: async (patch) => {
118
+ try {
119
+ const settings = await api<AppSettings>('PUT', '/settings', patch)
120
+ set({ appSettings: settings })
121
+ } catch (err) {
122
+ console.warn('Store error:', err)
123
+ }
124
+ },
125
+ secrets: {},
126
+ loadSecrets: async () => {
127
+ try {
128
+ const secrets = await api<Record<string, OrchestratorSecret>>('GET', '/secrets')
129
+ setIfChanged<AppState>(set, 'secrets', secrets)
130
+ } catch (err) {
131
+ console.warn('Store error:', err)
132
+ setIfChanged<AppState>(set, 'secrets', {})
133
+ }
134
+ },
135
+ providerConfigs: [],
136
+ loadProviderConfigs: async () => {
137
+ try {
138
+ const configs = await api<ProviderConfig[]>('GET', '/providers/configs')
139
+ setIfChanged<AppState>(set, 'providerConfigs', configs)
140
+ } catch (err) {
141
+ console.warn('Store error:', err)
142
+ setIfChanged<AppState>(set, 'providerConfigs', [])
143
+ }
144
+ },
145
+ gatewayProfiles: [],
146
+ loadGatewayProfiles: async () => {
147
+ try {
148
+ const gatewayProfiles = await api<GatewayProfile[]>('GET', '/gateways')
149
+ setIfChanged<AppState>(set, 'gatewayProfiles', gatewayProfiles)
150
+ } catch (err) {
151
+ console.warn('Store error:', err)
152
+ setIfChanged<AppState>(set, 'gatewayProfiles', [])
153
+ }
154
+ },
155
+ skills: {},
156
+ loadSkills: async () => {
157
+ try {
158
+ const skills = await api<Record<string, Skill>>('GET', '/skills')
159
+ setIfChanged<AppState>(set, 'skills', skills)
160
+ } catch (err) {
161
+ console.warn('Store error:', err)
162
+ setIfChanged<AppState>(set, 'skills', {})
163
+ }
164
+ },
165
+ connectors: {},
166
+ loadConnectors: async () => {
167
+ try {
168
+ const connectors = await api<Record<string, Connector>>('GET', '/connectors')
169
+ setIfChanged<AppState>(set, 'connectors', connectors)
170
+ } catch (err) {
171
+ console.warn('Store error:', err)
172
+ setIfChanged<AppState>(set, 'connectors', {})
173
+ }
174
+ },
175
+ webhooks: {},
176
+ loadWebhooks: async () => {
177
+ try {
178
+ const webhooks = await api<Record<string, Webhook>>('GET', '/webhooks')
179
+ setIfChanged<AppState>(set, 'webhooks', webhooks)
180
+ } catch (err) {
181
+ console.warn('Store error:', err)
182
+ setIfChanged<AppState>(set, 'webhooks', {})
183
+ }
184
+ },
185
+ mcpServers: {},
186
+ loadMcpServers: async () => {
187
+ try {
188
+ const mcpServers = await api<Record<string, McpServerConfig>>('GET', '/mcp-servers')
189
+ setIfChanged<AppState>(set, 'mcpServers', mcpServers)
190
+ } catch (err) {
191
+ console.warn('Store error:', err)
192
+ setIfChanged<AppState>(set, 'mcpServers', {})
193
+ }
194
+ },
195
+ plugins: {},
196
+ loadPlugins: async () => {
197
+ try {
198
+ const list = await api<PluginMeta[]>('GET', '/plugins')
199
+ const plugins: Record<string, PluginMeta> = {}
200
+ for (const p of list) plugins[p.filename] = p
201
+ setIfChanged<AppState>(set, 'plugins', plugins)
202
+ } catch (err) {
203
+ console.warn('Store error:', err)
204
+ setIfChanged<AppState>(set, 'plugins', {})
205
+ }
206
+ },
207
+ projects: {},
208
+ loadProjects: async () => {
209
+ try {
210
+ const projects = await api<Record<string, Project>>('GET', '/projects')
211
+ setIfChanged<AppState>(set, 'projects', projects)
212
+ } catch (err) {
213
+ console.warn('Store error:', err)
214
+ setIfChanged<AppState>(set, 'projects', {})
215
+ }
216
+ },
217
+ activityEntries: [],
218
+ loadActivity: async (filters) => {
219
+ try {
220
+ const params = new URLSearchParams()
221
+ if (filters?.entityType) params.set('entityType', filters.entityType)
222
+ if (filters?.limit) params.set('limit', String(filters.limit))
223
+ const qs = params.toString()
224
+ const entries = await api<ActivityEntry[]>('GET', `/activity${qs ? `?${qs}` : ''}`)
225
+ setIfChanged<AppState>(set, 'activityEntries', entries)
226
+ } catch (err) {
227
+ console.warn('Store error:', err)
228
+ setIfChanged<AppState>(set, 'activityEntries', [])
229
+ }
230
+ },
231
+ lastReadTimestamps: safeStorageGetJson<Record<string, number>>('sc_last_read', {}),
232
+ markChatRead: (id) => {
233
+ const ts = { ...get().lastReadTimestamps, [id]: Date.now() }
234
+ set({ lastReadTimestamps: ts })
235
+ safeStorageSet('sc_last_read', JSON.stringify(ts))
236
+ },
237
+ approvals: {},
238
+ loadApprovals: async () => {
239
+ try {
240
+ const list = await api<ApprovalRequest[]>('GET', '/approvals')
241
+ const approvals: Record<string, ApprovalRequest> = {}
242
+ for (const a of list) approvals[a.id] = a
243
+ setIfChanged<AppState>(set, 'approvals', approvals)
244
+ } catch (err) { console.warn('Store error:', err) }
245
+ },
246
+ submitApprovalDecision: async (id, approved) => {
247
+ try {
248
+ await api('POST', '/approvals', { id, approved })
249
+ await get().loadApprovals()
250
+ } catch (err) { console.warn('Store error:', err) }
251
+ },
252
+ notifications: [],
253
+ unreadNotificationCount: 0,
254
+ loadNotifications: async () => {
255
+ try {
256
+ const notifications = await api<AppNotification[]>('GET', '/notifications')
257
+ if (setIfChanged<AppState>(set, 'notifications', notifications)) {
258
+ set({ unreadNotificationCount: notifications.filter((n) => !n.read).length })
259
+ }
260
+ } catch (err) {
261
+ console.warn('Store error:', err)
262
+ if (setIfChanged<AppState>(set, 'notifications', [])) {
263
+ set({ unreadNotificationCount: 0 })
264
+ }
265
+ }
266
+ },
267
+ markNotificationRead: async (id) => {
268
+ const notifications = get().notifications.map((n) =>
269
+ n.id === id ? { ...n, read: true } : n,
270
+ )
271
+ set({
272
+ notifications,
273
+ unreadNotificationCount: notifications.filter((n) => !n.read).length,
274
+ })
275
+ try {
276
+ await api('PUT', `/notifications/${id}`, { read: true })
277
+ } catch (err) {
278
+ console.warn('Store error:', err)
279
+ }
280
+ },
281
+ markAllNotificationsRead: async () => {
282
+ const notifications = get().notifications.map((n) => ({ ...n, read: true }))
283
+ set({ notifications, unreadNotificationCount: 0 })
284
+ try {
285
+ await Promise.all(
286
+ get().notifications.filter((n) => !n.read).map((n) => api('PUT', `/notifications/${n.id}`, { read: true })),
287
+ )
288
+ } catch (err) {
289
+ console.warn('Store error:', err)
290
+ }
291
+ },
292
+ clearReadNotifications: async () => {
293
+ const notifications = get().notifications.filter((n) => !n.read)
294
+ set({ notifications, unreadNotificationCount: notifications.length })
295
+ try {
296
+ await api('DELETE', '/notifications')
297
+ } catch (err) {
298
+ console.warn('Store error:', err)
299
+ }
300
+ }
301
+ })
@@ -0,0 +1,7 @@
1
+
2
+ export * from './auth-slice'
3
+ export * from './session-slice'
4
+ export * from './ui-slice'
5
+ export * from './agent-slice'
6
+ export * from './task-slice'
7
+ export * from './data-slice'
@@ -0,0 +1,112 @@
1
+ const inflightSessionRefreshes = new Map<string, Promise<void>>()
2
+ import { StateCreator } from 'zustand'
3
+ import type { AppState } from '../use-app-store'
4
+ import type { Sessions, Session } from '../../types'
5
+ import { fetchChat, fetchChats } from '../../lib/chats'
6
+ import { api } from '../../lib/api-client'
7
+ import { errorMessage } from '../../lib/shared-utils'
8
+ import { setIfChanged, invalidateFingerprint } from '../set-if-changed'
9
+
10
+ export interface SessionSlice {
11
+ sessions: Sessions
12
+ currentSessionId: string | null
13
+ loadSessions: () => Promise<void>
14
+ refreshSession: (id: string) => Promise<void>
15
+ setCurrentSession: (id: string | null) => void
16
+ removeSession: (id: string) => void
17
+ clearSessions: (ids: string[]) => Promise<void>
18
+ togglePinSession: (id: string) => void
19
+ updateSessionInStore: (session: Session) => void
20
+ forkSession: (sessionId: string, messageIndex: number) => Promise<string | null>
21
+ }
22
+
23
+ export const createSessionSlice: StateCreator<AppState, [], [], SessionSlice> = (set, get) => ({
24
+ sessions: {},
25
+ currentSessionId: null,
26
+ loadSessions: async () => {
27
+ try {
28
+ const sessions = await fetchChats()
29
+ const changed = setIfChanged<AppState>(set, 'sessions', sessions)
30
+ if (changed) {
31
+ const currentSessionId = get().currentSessionId
32
+ if (currentSessionId && !sessions[currentSessionId]) {
33
+ set({ currentSessionId: null })
34
+ }
35
+ }
36
+ } catch (err) {
37
+ console.warn('Store error:', err)
38
+ }
39
+ },
40
+ refreshSession: async (id) => {
41
+ if (!id) return
42
+ const existing = inflightSessionRefreshes.get(id)
43
+ if (existing) {
44
+ await existing
45
+ return
46
+ }
47
+
48
+ const refreshPromise = (async () => {
49
+ try {
50
+ const session = await fetchChat(id)
51
+ const currentSessionId = get().currentSessionId
52
+ invalidateFingerprint('sessions')
53
+ set({
54
+ sessions: { ...get().sessions, [id]: session },
55
+ currentSessionId: currentSessionId && currentSessionId === id ? id : currentSessionId,
56
+ })
57
+ } catch (err) {
58
+ console.warn('Store error:', err)
59
+ }
60
+ })()
61
+
62
+ inflightSessionRefreshes.set(id, refreshPromise)
63
+ try {
64
+ await refreshPromise
65
+ } finally {
66
+ if (inflightSessionRefreshes.get(id) === refreshPromise) {
67
+ inflightSessionRefreshes.delete(id)
68
+ }
69
+ }
70
+ },
71
+ setCurrentSession: (id) => set({ currentSessionId: id }),
72
+ removeSession: (id) => {
73
+ const sessions = { ...get().sessions }
74
+ delete sessions[id]
75
+ invalidateFingerprint('sessions')
76
+ set({ sessions, currentSessionId: get().currentSessionId === id ? null : get().currentSessionId })
77
+ },
78
+ clearSessions: async (ids) => {
79
+ if (!ids.length) return
80
+ await api('DELETE', '/chats', { ids })
81
+ const sessions = { ...get().sessions }
82
+ for (const id of ids) delete sessions[id]
83
+ invalidateFingerprint('sessions')
84
+ set({ sessions, currentSessionId: ids.includes(get().currentSessionId!) ? null : get().currentSessionId })
85
+ },
86
+ togglePinSession: (id) => {
87
+ const sessions = { ...get().sessions }
88
+ if (sessions[id]) {
89
+ sessions[id] = { ...sessions[id], pinned: !sessions[id].pinned }
90
+ invalidateFingerprint('sessions')
91
+ set({ sessions })
92
+ // Persist to server
93
+ void api('PUT', `/chats/${id}`, { pinned: sessions[id].pinned })
94
+ }
95
+ },
96
+ updateSessionInStore: (session) => {
97
+ invalidateFingerprint('sessions')
98
+ set({ sessions: { ...get().sessions, [session.id]: session } })
99
+ },
100
+ forkSession: async (sessionId, messageIndex) => {
101
+ try {
102
+ const forked = await api<Session>('POST', `/chats/${sessionId}/fork`, { messageIndex })
103
+ if (!forked?.id) return null
104
+ await get().loadSessions()
105
+ set({ currentSessionId: forked.id })
106
+ return forked.id
107
+ } catch (err: unknown) {
108
+ console.error('Fork failed:', errorMessage(err))
109
+ return null
110
+ }
111
+ }
112
+ })
@@ -0,0 +1,63 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AppState } from '../use-app-store'
3
+ import type { BoardTask } from '../../types'
4
+ import { fetchTasks } from '../../lib/tasks'
5
+ import { api } from '../../lib/api-client'
6
+ import { setIfChanged, invalidateFingerprint } from '../set-if-changed'
7
+
8
+ export interface TaskSlice {
9
+ tasks: Record<string, BoardTask>
10
+ loadTasks: (includeArchived?: boolean) => Promise<void>
11
+ optimisticUpdateTask: (taskId: string, patch: Partial<BoardTask>) => Promise<boolean>
12
+ optimisticDeleteTask: (taskId: string) => Promise<boolean>
13
+ showArchivedTasks: boolean
14
+ setShowArchivedTasks: (show: boolean) => void
15
+ }
16
+
17
+ export const createTaskSlice: StateCreator<AppState, [], [], TaskSlice> = (set, get) => ({
18
+ tasks: {},
19
+ loadTasks: async (includeArchived) => {
20
+ try {
21
+ const show = includeArchived ?? get().showArchivedTasks
22
+ const tasks = await fetchTasks(show)
23
+ setIfChanged<AppState>(set, 'tasks', tasks)
24
+ } catch (err) {
25
+ console.warn('Store error:', err)
26
+ }
27
+ },
28
+ optimisticUpdateTask: async (taskId, patch) => {
29
+ const prev = get().tasks[taskId]
30
+ if (!prev) return false
31
+ invalidateFingerprint('tasks')
32
+ set({ tasks: { ...get().tasks, [taskId]: { ...prev, ...patch, updatedAt: Date.now() } } })
33
+ try {
34
+ await api('PUT', `/tasks/${taskId}`, patch)
35
+ return true
36
+ } catch {
37
+ invalidateFingerprint('tasks')
38
+ set({ tasks: { ...get().tasks, [taskId]: prev } })
39
+ return false
40
+ }
41
+ },
42
+ optimisticDeleteTask: async (taskId) => {
43
+ const prev = get().tasks[taskId]
44
+ if (!prev) return false
45
+ const next = { ...get().tasks }
46
+ delete next[taskId]
47
+ invalidateFingerprint('tasks')
48
+ set({ tasks: next })
49
+ try {
50
+ await api('DELETE', `/tasks/${taskId}`)
51
+ return true
52
+ } catch {
53
+ invalidateFingerprint('tasks')
54
+ set({ tasks: { ...get().tasks, [taskId]: prev } })
55
+ return false
56
+ }
57
+ },
58
+ showArchivedTasks: false,
59
+ setShowArchivedTasks: (show) => {
60
+ set({ showArchivedTasks: show })
61
+ get().loadTasks(show)
62
+ }
63
+ })
@@ -0,0 +1,192 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AppState } from '../use-app-store'
3
+ import type { AppView, FleetFilter } from '../../types'
4
+ import { safeStorageGet, safeStorageSet } from '../../lib/safe-storage'
5
+
6
+ export interface UiSlice {
7
+ sidebarOpen: boolean
8
+ setSidebarOpen: (open: boolean) => void
9
+ toggleSidebar: () => void
10
+ settingsOpen: boolean
11
+ setSettingsOpen: (open: boolean) => void
12
+ activeView: AppView
13
+ setActiveView: (view: AppView) => void
14
+ agentSheetOpen: boolean
15
+ setAgentSheetOpen: (open: boolean) => void
16
+ editingAgentId: string | null
17
+ setEditingAgentId: (id: string | null) => void
18
+ scheduleSheetOpen: boolean
19
+ setScheduleSheetOpen: (open: boolean) => void
20
+ editingScheduleId: string | null
21
+ setEditingScheduleId: (id: string | null) => void
22
+ scheduleTemplatePrefill: { name: string; taskPrompt: string; scheduleType: 'cron' | 'interval'; cron?: string; intervalMs?: number } | null
23
+ setScheduleTemplatePrefill: (prefill: { name: string; taskPrompt: string; scheduleType: 'cron' | 'interval'; cron?: string; intervalMs?: number } | null) => void
24
+ memorySheetOpen: boolean
25
+ setMemorySheetOpen: (open: boolean) => void
26
+ selectedMemoryId: string | null
27
+ setSelectedMemoryId: (id: string | null) => void
28
+ memoryRefreshKey: number
29
+ triggerMemoryRefresh: () => void
30
+ memoryAgentFilter: string | null
31
+ setMemoryAgentFilter: (agentId: string | null) => void
32
+ memoryTierFilter: 'all' | 'working' | 'durable' | 'archive'
33
+ setMemoryTierFilter: (tier: 'all' | 'working' | 'durable' | 'archive') => void
34
+ memoryScopeFilter: 'all' | 'global' | 'agent' | 'session' | 'project'
35
+ setMemoryScopeFilter: (scope: 'all' | 'global' | 'agent' | 'session' | 'project') => void
36
+ secretSheetOpen: boolean
37
+ setSecretSheetOpen: (open: boolean) => void
38
+ editingSecretId: string | null
39
+ setEditingSecretId: (id: string | null) => void
40
+ taskSheetOpen: boolean
41
+ setTaskSheetOpen: (open: boolean) => void
42
+ editingTaskId: string | null
43
+ setEditingTaskId: (id: string | null) => void
44
+ taskSheetViewOnly: boolean
45
+ setTaskSheetViewOnly: (v: boolean) => void
46
+ providerSheetOpen: boolean
47
+ setProviderSheetOpen: (open: boolean) => void
48
+ editingProviderId: string | null
49
+ setEditingProviderId: (id: string | null) => void
50
+ gatewaySheetOpen: boolean
51
+ setGatewaySheetOpen: (open: boolean) => void
52
+ editingGatewayId: string | null
53
+ setEditingGatewayId: (id: string | null) => void
54
+ skillSheetOpen: boolean
55
+ setSkillSheetOpen: (open: boolean) => void
56
+ editingSkillId: string | null
57
+ setEditingSkillId: (id: string | null) => void
58
+ connectorSheetOpen: boolean
59
+ setConnectorSheetOpen: (open: boolean) => void
60
+ editingConnectorId: string | null
61
+ setEditingConnectorId: (id: string | null) => void
62
+ webhookSheetOpen: boolean
63
+ setWebhookSheetOpen: (open: boolean) => void
64
+ editingWebhookId: string | null
65
+ setEditingWebhookId: (id: string | null) => void
66
+ mcpServerSheetOpen: boolean
67
+ setMcpServerSheetOpen: (open: boolean) => void
68
+ editingMcpServerId: string | null
69
+ setEditingMcpServerId: (id: string | null) => void
70
+ knowledgeSheetOpen: boolean
71
+ setKnowledgeSheetOpen: (open: boolean) => void
72
+ editingKnowledgeId: string | null
73
+ setEditingKnowledgeId: (id: string | null) => void
74
+ knowledgeRefreshKey: number
75
+ triggerKnowledgeRefresh: () => void
76
+ pluginSheetOpen: boolean
77
+ setPluginSheetOpen: (open: boolean) => void
78
+ editingPluginFilename: string | null
79
+ setEditingPluginFilename: (filename: string | null) => void
80
+ projectSheetOpen: boolean
81
+ setProjectSheetOpen: (open: boolean) => void
82
+ editingProjectId: string | null
83
+ setEditingProjectId: (id: string | null) => void
84
+ activeProjectFilter: string | null
85
+ setActiveProjectFilter: (id: string | null) => void
86
+ showTrash: boolean
87
+ setShowTrash: (show: boolean) => void
88
+ inspectorOpen: boolean
89
+ setInspectorOpen: (open: boolean) => void
90
+ inspectorTab: 'overview' | 'files' | 'skills' | 'automations' | 'advanced'
91
+ setInspectorTab: (tab: 'overview' | 'files' | 'skills' | 'automations' | 'advanced') => void
92
+ fleetFilter: FleetFilter
93
+ setFleetFilter: (filter: FleetFilter) => void
94
+ chatFilter: 'all' | 'active' | 'recent'
95
+ setChatFilter: (filter: 'all' | 'active' | 'recent') => void
96
+ walletPanelAgentId: string | null
97
+ setWalletPanelAgentId: (id: string | null) => void
98
+ }
99
+
100
+ export const createUiSlice: StateCreator<AppState, [], [], UiSlice> = (set, get) => ({
101
+ sidebarOpen: false,
102
+ setSidebarOpen: (open) => set({ sidebarOpen: open }),
103
+ toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
104
+ settingsOpen: false,
105
+ setSettingsOpen: (open) => set({ settingsOpen: open }),
106
+ activeView: 'home',
107
+ setActiveView: (view) => set({ activeView: view }),
108
+ agentSheetOpen: false,
109
+ setAgentSheetOpen: (open) => set({ agentSheetOpen: open }),
110
+ editingAgentId: null,
111
+ setEditingAgentId: (id) => set({ editingAgentId: id }),
112
+ scheduleSheetOpen: false,
113
+ setScheduleSheetOpen: (open) => set({ scheduleSheetOpen: open }),
114
+ editingScheduleId: null,
115
+ setEditingScheduleId: (id) => set({ editingScheduleId: id }),
116
+ scheduleTemplatePrefill: null,
117
+ setScheduleTemplatePrefill: (prefill) => set({ scheduleTemplatePrefill: prefill }),
118
+ memorySheetOpen: false,
119
+ setMemorySheetOpen: (open) => set({ memorySheetOpen: open }),
120
+ selectedMemoryId: null,
121
+ setSelectedMemoryId: (id) => set({ selectedMemoryId: id }),
122
+ memoryRefreshKey: 0,
123
+ triggerMemoryRefresh: () => set((s) => ({ memoryRefreshKey: s.memoryRefreshKey + 1 })),
124
+ memoryAgentFilter: null,
125
+ setMemoryAgentFilter: (agentId) => set({ memoryAgentFilter: agentId }),
126
+ memoryTierFilter: 'all',
127
+ setMemoryTierFilter: (tier) => set({ memoryTierFilter: tier }),
128
+ memoryScopeFilter: 'all',
129
+ setMemoryScopeFilter: (scope) => set({ memoryScopeFilter: scope }),
130
+ secretSheetOpen: false,
131
+ setSecretSheetOpen: (open) => set({ secretSheetOpen: open }),
132
+ editingSecretId: null,
133
+ setEditingSecretId: (id) => set({ editingSecretId: id }),
134
+ taskSheetOpen: false,
135
+ setTaskSheetOpen: (open) => set({ taskSheetOpen: open, ...(open ? {} : { taskSheetViewOnly: false }) }),
136
+ editingTaskId: null,
137
+ setEditingTaskId: (id) => set({ editingTaskId: id }),
138
+ taskSheetViewOnly: false,
139
+ setTaskSheetViewOnly: (v) => set({ taskSheetViewOnly: v }),
140
+ providerSheetOpen: false,
141
+ setProviderSheetOpen: (open) => set({ providerSheetOpen: open }),
142
+ editingProviderId: null,
143
+ setEditingProviderId: (id) => set({ editingProviderId: id }),
144
+ gatewaySheetOpen: false,
145
+ setGatewaySheetOpen: (open) => set({ gatewaySheetOpen: open }),
146
+ editingGatewayId: null,
147
+ setEditingGatewayId: (id) => set({ editingGatewayId: id }),
148
+ skillSheetOpen: false,
149
+ setSkillSheetOpen: (open) => set({ skillSheetOpen: open }),
150
+ editingSkillId: null,
151
+ setEditingSkillId: (id) => set({ editingSkillId: id }),
152
+ connectorSheetOpen: false,
153
+ setConnectorSheetOpen: (open) => set({ connectorSheetOpen: open }),
154
+ editingConnectorId: null,
155
+ setEditingConnectorId: (id) => set({ editingConnectorId: id }),
156
+ webhookSheetOpen: false,
157
+ setWebhookSheetOpen: (open) => set({ webhookSheetOpen: open }),
158
+ editingWebhookId: null,
159
+ setEditingWebhookId: (id) => set({ editingWebhookId: id }),
160
+ mcpServerSheetOpen: false,
161
+ setMcpServerSheetOpen: (open) => set({ mcpServerSheetOpen: open }),
162
+ editingMcpServerId: null,
163
+ setEditingMcpServerId: (id) => set({ editingMcpServerId: id }),
164
+ knowledgeSheetOpen: false,
165
+ setKnowledgeSheetOpen: (open) => set({ knowledgeSheetOpen: open }),
166
+ editingKnowledgeId: null,
167
+ setEditingKnowledgeId: (id) => set({ editingKnowledgeId: id }),
168
+ knowledgeRefreshKey: 0,
169
+ triggerKnowledgeRefresh: () => set((s) => ({ knowledgeRefreshKey: s.knowledgeRefreshKey + 1 })),
170
+ pluginSheetOpen: false,
171
+ setPluginSheetOpen: (open) => set({ pluginSheetOpen: open }),
172
+ editingPluginFilename: null,
173
+ setEditingPluginFilename: (filename) => set({ editingPluginFilename: filename }),
174
+ projectSheetOpen: false,
175
+ setProjectSheetOpen: (open) => set({ projectSheetOpen: open }),
176
+ editingProjectId: null,
177
+ setEditingProjectId: (id) => set({ editingProjectId: id }),
178
+ activeProjectFilter: null,
179
+ setActiveProjectFilter: (id) => set({ activeProjectFilter: id }),
180
+ showTrash: false,
181
+ setShowTrash: (show) => set({ showTrash: show }),
182
+ inspectorOpen: false,
183
+ setInspectorOpen: (open) => set({ inspectorOpen: open }),
184
+ inspectorTab: 'overview',
185
+ setInspectorTab: (tab) => set({ inspectorTab: tab }),
186
+ fleetFilter: (safeStorageGet('sc_fleet_filter') as FleetFilter) || 'all',
187
+ setFleetFilter: (filter) => { safeStorageSet('sc_fleet_filter', filter); set({ fleetFilter: filter }) },
188
+ chatFilter: 'all' as const,
189
+ setChatFilter: (filter) => set({ chatFilter: filter }),
190
+ walletPanelAgentId: null,
191
+ setWalletPanelAgentId: (id) => set({ walletPanelAgentId: id })
192
+ })