@swarmclawai/swarmclaw 0.7.2 → 0.7.4

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 (274) hide show
  1. package/README.md +116 -50
  2. package/bin/package-manager.js +157 -0
  3. package/bin/package-manager.test.js +90 -0
  4. package/bin/server-cmd.js +38 -7
  5. package/bin/swarmclaw.js +54 -4
  6. package/bin/update-cmd.js +48 -10
  7. package/bin/update-cmd.test.js +55 -0
  8. package/package.json +8 -3
  9. package/scripts/postinstall.mjs +26 -0
  10. package/src/app/api/agents/[id]/route.ts +43 -0
  11. package/src/app/api/agents/[id]/thread/route.ts +39 -8
  12. package/src/app/api/agents/route.ts +35 -2
  13. package/src/app/api/auth/route.ts +77 -8
  14. package/src/app/api/chatrooms/[id]/chat/route.ts +22 -6
  15. package/src/app/api/chatrooms/[id]/pins/route.ts +2 -1
  16. package/src/app/api/chatrooms/[id]/reactions/route.ts +2 -1
  17. package/src/app/api/chatrooms/[id]/route.ts +6 -0
  18. package/src/app/api/chats/[id]/browser/route.ts +5 -1
  19. package/src/app/api/chats/[id]/chat/route.ts +7 -3
  20. package/src/app/api/chats/[id]/messages/route.ts +19 -13
  21. package/src/app/api/chats/[id]/route.ts +30 -0
  22. package/src/app/api/chats/[id]/stop/route.ts +6 -1
  23. package/src/app/api/chats/heartbeat/route.ts +2 -1
  24. package/src/app/api/chats/route.ts +23 -1
  25. package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
  26. package/src/app/api/connectors/doctor/route.ts +13 -0
  27. package/src/app/api/external-agents/[id]/heartbeat/route.ts +33 -0
  28. package/src/app/api/external-agents/[id]/route.ts +31 -0
  29. package/src/app/api/external-agents/register/route.ts +3 -0
  30. package/src/app/api/external-agents/route.ts +66 -0
  31. package/src/app/api/files/open/route.ts +16 -14
  32. package/src/app/api/gateways/[id]/health/route.ts +28 -0
  33. package/src/app/api/gateways/[id]/route.ts +79 -0
  34. package/src/app/api/gateways/route.ts +57 -0
  35. package/src/app/api/memory/maintenance/route.ts +11 -1
  36. package/src/app/api/openclaw/agent-files/route.ts +27 -4
  37. package/src/app/api/openclaw/gateway/route.ts +10 -7
  38. package/src/app/api/openclaw/skills/route.ts +12 -4
  39. package/src/app/api/plugins/dependencies/route.ts +24 -0
  40. package/src/app/api/plugins/install/route.ts +15 -92
  41. package/src/app/api/plugins/route.ts +3 -26
  42. package/src/app/api/plugins/settings/route.ts +17 -12
  43. package/src/app/api/plugins/ui/route.ts +1 -0
  44. package/src/app/api/providers/[id]/discover-models/route.ts +27 -0
  45. package/src/app/api/schedules/[id]/route.ts +38 -9
  46. package/src/app/api/schedules/route.ts +51 -28
  47. package/src/app/api/settings/route.ts +55 -17
  48. package/src/app/api/setup/doctor/route.ts +6 -4
  49. package/src/app/api/tasks/[id]/route.ts +16 -6
  50. package/src/app/api/tasks/bulk/route.ts +3 -3
  51. package/src/app/api/tasks/route.ts +9 -4
  52. package/src/app/api/webhooks/[id]/route.ts +8 -1
  53. package/src/app/page.tsx +135 -17
  54. package/src/cli/binary.test.js +142 -0
  55. package/src/cli/index.js +38 -11
  56. package/src/cli/index.test.js +195 -0
  57. package/src/cli/index.ts +21 -12
  58. package/src/cli/server-cmd.test.js +59 -0
  59. package/src/cli/spec.js +20 -2
  60. package/src/components/agents/agent-card.tsx +15 -12
  61. package/src/components/agents/agent-chat-list.tsx +101 -1
  62. package/src/components/agents/agent-list.tsx +46 -9
  63. package/src/components/agents/agent-sheet.tsx +456 -23
  64. package/src/components/agents/inspector-panel.tsx +110 -49
  65. package/src/components/agents/sandbox-env-panel.tsx +4 -1
  66. package/src/components/auth/access-key-gate.tsx +36 -97
  67. package/src/components/auth/setup-wizard.tsx +970 -275
  68. package/src/components/chat/chat-area.tsx +70 -27
  69. package/src/components/chat/chat-card.tsx +6 -21
  70. package/src/components/chat/chat-header.tsx +263 -366
  71. package/src/components/chat/chat-list.tsx +62 -26
  72. package/src/components/chat/checkpoint-timeline.tsx +1 -1
  73. package/src/components/chat/message-list.tsx +145 -19
  74. package/src/components/chatrooms/chatroom-input.tsx +96 -33
  75. package/src/components/chatrooms/chatroom-list.tsx +141 -72
  76. package/src/components/chatrooms/chatroom-message.tsx +7 -6
  77. package/src/components/chatrooms/chatroom-sheet.tsx +13 -1
  78. package/src/components/chatrooms/chatroom-tool-request-banner.tsx +5 -2
  79. package/src/components/chatrooms/chatroom-view.tsx +422 -209
  80. package/src/components/chatrooms/reaction-picker.tsx +38 -33
  81. package/src/components/connectors/connector-list.tsx +265 -127
  82. package/src/components/connectors/connector-sheet.tsx +217 -0
  83. package/src/components/gateways/gateway-sheet.tsx +567 -0
  84. package/src/components/home/home-view.tsx +128 -4
  85. package/src/components/input/chat-input.tsx +135 -86
  86. package/src/components/layout/app-layout.tsx +385 -194
  87. package/src/components/layout/mobile-header.tsx +26 -8
  88. package/src/components/memory/memory-browser.tsx +71 -6
  89. package/src/components/memory/memory-card.tsx +18 -0
  90. package/src/components/memory/memory-detail.tsx +58 -31
  91. package/src/components/memory/memory-sheet.tsx +32 -4
  92. package/src/components/plugins/plugin-list.tsx +15 -3
  93. package/src/components/plugins/plugin-sheet.tsx +118 -9
  94. package/src/components/projects/project-detail.tsx +189 -1
  95. package/src/components/providers/provider-list.tsx +158 -2
  96. package/src/components/providers/provider-sheet.tsx +81 -70
  97. package/src/components/shared/agent-picker-list.tsx +2 -2
  98. package/src/components/shared/bottom-sheet.tsx +31 -15
  99. package/src/components/shared/command-palette.tsx +111 -24
  100. package/src/components/shared/confirm-dialog.tsx +45 -30
  101. package/src/components/shared/model-combobox.tsx +90 -8
  102. package/src/components/shared/settings/plugin-manager.tsx +20 -4
  103. package/src/components/shared/settings/section-capability-policy.tsx +105 -0
  104. package/src/components/shared/settings/section-heartbeat.tsx +88 -6
  105. package/src/components/shared/settings/section-orchestrator.tsx +6 -3
  106. package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
  107. package/src/components/shared/settings/section-secrets.tsx +6 -6
  108. package/src/components/shared/settings/section-user-preferences.tsx +1 -1
  109. package/src/components/shared/settings/section-voice.tsx +5 -1
  110. package/src/components/shared/settings/section-web-search.tsx +10 -2
  111. package/src/components/shared/settings/settings-page.tsx +248 -47
  112. package/src/components/tasks/approvals-panel.tsx +211 -18
  113. package/src/components/tasks/task-board.tsx +242 -46
  114. package/src/components/ui/dialog.tsx +2 -2
  115. package/src/components/usage/metrics-dashboard.tsx +74 -1
  116. package/src/components/wallets/wallet-approval-dialog.tsx +59 -54
  117. package/src/components/wallets/wallet-panel.tsx +17 -5
  118. package/src/components/webhooks/webhook-sheet.tsx +7 -7
  119. package/src/lib/auth.ts +17 -0
  120. package/src/lib/chat-streaming-state.test.ts +108 -0
  121. package/src/lib/chat-streaming-state.ts +108 -0
  122. package/src/lib/heartbeat-defaults.ts +48 -0
  123. package/src/lib/memory-presentation.ts +59 -0
  124. package/src/lib/openclaw-agent-id.test.ts +14 -0
  125. package/src/lib/openclaw-agent-id.ts +31 -0
  126. package/src/lib/provider-model-discovery-client.ts +29 -0
  127. package/src/lib/providers/index.ts +12 -5
  128. package/src/lib/runtime-loop.ts +105 -3
  129. package/src/lib/safe-storage.ts +6 -1
  130. package/src/lib/server/agent-assignment.test.ts +112 -0
  131. package/src/lib/server/agent-assignment.ts +169 -0
  132. package/src/lib/server/agent-runtime-config.test.ts +141 -0
  133. package/src/lib/server/agent-runtime-config.ts +277 -0
  134. package/src/lib/server/approval-connector-notify.test.ts +253 -0
  135. package/src/lib/server/approvals-auto-approve.test.ts +264 -0
  136. package/src/lib/server/approvals.ts +483 -75
  137. package/src/lib/server/autonomy-runtime.test.ts +341 -0
  138. package/src/lib/server/browser-state.test.ts +118 -0
  139. package/src/lib/server/browser-state.ts +123 -0
  140. package/src/lib/server/build-llm.test.ts +44 -0
  141. package/src/lib/server/build-llm.ts +11 -4
  142. package/src/lib/server/builtin-plugins.ts +34 -0
  143. package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
  144. package/src/lib/server/chat-execution-tool-events.test.ts +219 -0
  145. package/src/lib/server/chat-execution.ts +402 -125
  146. package/src/lib/server/chatroom-health.test.ts +26 -0
  147. package/src/lib/server/chatroom-health.ts +2 -3
  148. package/src/lib/server/chatroom-helpers.test.ts +74 -2
  149. package/src/lib/server/chatroom-helpers.ts +144 -11
  150. package/src/lib/server/chatroom-session-persistence.test.ts +87 -0
  151. package/src/lib/server/connectors/discord.ts +175 -11
  152. package/src/lib/server/connectors/doctor.test.ts +80 -0
  153. package/src/lib/server/connectors/doctor.ts +116 -0
  154. package/src/lib/server/connectors/manager.ts +994 -130
  155. package/src/lib/server/connectors/policy.test.ts +222 -0
  156. package/src/lib/server/connectors/policy.ts +452 -0
  157. package/src/lib/server/connectors/slack.ts +189 -10
  158. package/src/lib/server/connectors/telegram.ts +65 -15
  159. package/src/lib/server/connectors/thread-context.test.ts +44 -0
  160. package/src/lib/server/connectors/thread-context.ts +72 -0
  161. package/src/lib/server/connectors/types.ts +41 -11
  162. package/src/lib/server/daemon-state.ts +62 -3
  163. package/src/lib/server/data-dir.ts +13 -0
  164. package/src/lib/server/delegation-jobs.test.ts +140 -0
  165. package/src/lib/server/delegation-jobs.ts +248 -0
  166. package/src/lib/server/document-utils.test.ts +47 -0
  167. package/src/lib/server/document-utils.ts +397 -0
  168. package/src/lib/server/eval/agent-regression.test.ts +47 -0
  169. package/src/lib/server/eval/agent-regression.ts +1742 -0
  170. package/src/lib/server/eval/runner.ts +11 -1
  171. package/src/lib/server/eval/store.ts +2 -1
  172. package/src/lib/server/heartbeat-service.ts +23 -43
  173. package/src/lib/server/heartbeat-source.test.ts +22 -0
  174. package/src/lib/server/heartbeat-source.ts +7 -0
  175. package/src/lib/server/identity-continuity.test.ts +77 -0
  176. package/src/lib/server/identity-continuity.ts +127 -0
  177. package/src/lib/server/mailbox-utils.ts +347 -0
  178. package/src/lib/server/main-agent-loop.ts +31 -964
  179. package/src/lib/server/memory-db.ts +4 -6
  180. package/src/lib/server/memory-tiers.ts +40 -0
  181. package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
  182. package/src/lib/server/openclaw-agent-resolver.ts +128 -0
  183. package/src/lib/server/openclaw-exec-config.ts +6 -5
  184. package/src/lib/server/openclaw-gateway.ts +123 -36
  185. package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
  186. package/src/lib/server/openclaw-skills-normalize.ts +136 -0
  187. package/src/lib/server/openclaw-sync.ts +3 -2
  188. package/src/lib/server/orchestrator-lg.ts +18 -8
  189. package/src/lib/server/orchestrator.ts +5 -4
  190. package/src/lib/server/playwright-proxy.mjs +27 -3
  191. package/src/lib/server/plugins.test.ts +215 -0
  192. package/src/lib/server/plugins.ts +832 -69
  193. package/src/lib/server/provider-health.ts +33 -3
  194. package/src/lib/server/provider-model-discovery.ts +481 -0
  195. package/src/lib/server/queue.ts +4 -21
  196. package/src/lib/server/runtime-settings.test.ts +119 -0
  197. package/src/lib/server/runtime-settings.ts +12 -92
  198. package/src/lib/server/schedule-normalization.ts +187 -0
  199. package/src/lib/server/scheduler.ts +2 -0
  200. package/src/lib/server/session-archive-memory.test.ts +85 -0
  201. package/src/lib/server/session-archive-memory.ts +230 -0
  202. package/src/lib/server/session-mailbox.ts +8 -18
  203. package/src/lib/server/session-reset-policy.test.ts +99 -0
  204. package/src/lib/server/session-reset-policy.ts +311 -0
  205. package/src/lib/server/session-run-manager.ts +33 -80
  206. package/src/lib/server/session-tools/autonomy-tools.test.ts +128 -0
  207. package/src/lib/server/session-tools/calendar.ts +2 -12
  208. package/src/lib/server/session-tools/connector.ts +109 -8
  209. package/src/lib/server/session-tools/context.ts +14 -2
  210. package/src/lib/server/session-tools/crawl.ts +447 -0
  211. package/src/lib/server/session-tools/crud.ts +96 -34
  212. package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
  213. package/src/lib/server/session-tools/delegate.ts +406 -20
  214. package/src/lib/server/session-tools/discovery-approvals.test.ts +170 -0
  215. package/src/lib/server/session-tools/discovery.ts +40 -12
  216. package/src/lib/server/session-tools/document.ts +283 -0
  217. package/src/lib/server/session-tools/email.ts +1 -3
  218. package/src/lib/server/session-tools/extract.ts +137 -0
  219. package/src/lib/server/session-tools/file-normalize.test.ts +98 -0
  220. package/src/lib/server/session-tools/file-send.test.ts +84 -1
  221. package/src/lib/server/session-tools/file.ts +243 -24
  222. package/src/lib/server/session-tools/http.ts +9 -3
  223. package/src/lib/server/session-tools/human-loop.ts +227 -0
  224. package/src/lib/server/session-tools/image-gen.ts +1 -3
  225. package/src/lib/server/session-tools/index.ts +87 -2
  226. package/src/lib/server/session-tools/mailbox.ts +276 -0
  227. package/src/lib/server/session-tools/manage-schedules.test.ts +137 -0
  228. package/src/lib/server/session-tools/memory.ts +35 -3
  229. package/src/lib/server/session-tools/monitor.ts +162 -12
  230. package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
  231. package/src/lib/server/session-tools/openclaw-nodes.test.ts +111 -0
  232. package/src/lib/server/session-tools/openclaw-nodes.ts +86 -20
  233. package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
  234. package/src/lib/server/session-tools/platform.ts +142 -4
  235. package/src/lib/server/session-tools/plugin-creator.ts +95 -25
  236. package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
  237. package/src/lib/server/session-tools/replicate.ts +1 -3
  238. package/src/lib/server/session-tools/sandbox.ts +51 -92
  239. package/src/lib/server/session-tools/schedule.ts +20 -10
  240. package/src/lib/server/session-tools/session-info.ts +58 -4
  241. package/src/lib/server/session-tools/session-tools-wiring.test.ts +54 -17
  242. package/src/lib/server/session-tools/shell.ts +2 -2
  243. package/src/lib/server/session-tools/subagent.ts +195 -27
  244. package/src/lib/server/session-tools/table.ts +587 -0
  245. package/src/lib/server/session-tools/wallet.ts +13 -10
  246. package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
  247. package/src/lib/server/session-tools/web.ts +947 -108
  248. package/src/lib/server/storage.ts +255 -10
  249. package/src/lib/server/stream-agent-chat.test.ts +61 -0
  250. package/src/lib/server/stream-agent-chat.ts +185 -25
  251. package/src/lib/server/structured-extract.test.ts +72 -0
  252. package/src/lib/server/structured-extract.ts +373 -0
  253. package/src/lib/server/task-mention.test.ts +16 -2
  254. package/src/lib/server/task-mention.ts +61 -11
  255. package/src/lib/server/tool-aliases.ts +80 -12
  256. package/src/lib/server/tool-capability-policy.ts +7 -1
  257. package/src/lib/server/tool-retry.ts +2 -0
  258. package/src/lib/server/watch-jobs.test.ts +173 -0
  259. package/src/lib/server/watch-jobs.ts +532 -0
  260. package/src/lib/server/ws-hub.ts +5 -3
  261. package/src/lib/setup-defaults.ts +352 -11
  262. package/src/lib/tool-definitions.ts +3 -4
  263. package/src/lib/validation/schemas.test.ts +26 -0
  264. package/src/lib/validation/schemas.ts +62 -1
  265. package/src/lib/ws-client.ts +14 -12
  266. package/src/proxy.ts +5 -5
  267. package/src/stores/use-app-store.ts +43 -7
  268. package/src/stores/use-chat-store.ts +31 -2
  269. package/src/stores/use-chatroom-store.ts +153 -26
  270. package/src/types/index.ts +470 -44
  271. package/src/app/api/chats/[id]/main-loop/route.ts +0 -94
  272. package/src/components/chat/new-chat-sheet.tsx +0 -253
  273. package/src/lib/server/main-session.ts +0 -17
  274. package/src/lib/server/session-run-manager.test.ts +0 -26
@@ -9,6 +9,7 @@ import { Avatar } from '@/components/shared/avatar'
9
9
  import { SettingsPage } from '@/components/shared/settings/settings-page'
10
10
  import { AgentList } from '@/components/agents/agent-list'
11
11
  import { AgentChatList } from '@/components/agents/agent-chat-list'
12
+ import { AgentAvatar } from '@/components/agents/agent-avatar'
12
13
  import { AgentSheet } from '@/components/agents/agent-sheet'
13
14
  import { ScheduleList } from '@/components/schedules/schedule-list'
14
15
  import { ScheduleSheet } from '@/components/schedules/schedule-sheet'
@@ -23,6 +24,7 @@ import { SecretsList } from '@/components/secrets/secrets-list'
23
24
  import { SecretSheet } from '@/components/secrets/secret-sheet'
24
25
  import { ProviderList } from '@/components/providers/provider-list'
25
26
  import { ProviderSheet } from '@/components/providers/provider-sheet'
27
+ import { GatewaySheet } from '@/components/gateways/gateway-sheet'
26
28
  import { SkillList } from '@/components/skills/skill-list'
27
29
  import { SkillSheet } from '@/components/skills/skill-sheet'
28
30
  import { ConnectorList } from '@/components/connectors/connector-list'
@@ -71,6 +73,46 @@ const RAIL_EXPANDED_KEY = 'sc_rail_expanded'
71
73
  const STAR_NOTIFICATION_KEY = 'sc_star_notification_v1'
72
74
  const GITHUB_REPO_URL = 'https://github.com/swarmclawai/swarmclaw'
73
75
 
76
+ const VIEW_LABELS: Record<AppView, string> = {
77
+ home: 'Home',
78
+ agents: 'Agents',
79
+ chatrooms: 'Chatrooms',
80
+ schedules: 'Schedules',
81
+ memory: 'Memory',
82
+ tasks: 'Tasks',
83
+ approvals: 'Approvals',
84
+ secrets: 'Secrets',
85
+ providers: 'Providers',
86
+ skills: 'Skills',
87
+ connectors: 'Connectors',
88
+ webhooks: 'Webhooks',
89
+ mcp_servers: 'MCP Servers',
90
+ knowledge: 'Knowledge',
91
+ logs: 'Logs',
92
+ plugins: 'Plugins',
93
+ usage: 'Usage',
94
+ wallets: 'Wallets',
95
+ runs: 'Runs',
96
+ settings: 'Settings',
97
+ projects: 'Projects',
98
+ activity: 'Activity',
99
+ }
100
+
101
+ const CREATE_LABELS: Partial<Record<AppView, string>> = {
102
+ agents: 'Agent',
103
+ schedules: 'Schedule',
104
+ tasks: 'Task',
105
+ secrets: 'Secret',
106
+ providers: 'Provider',
107
+ skills: 'Skill',
108
+ connectors: 'Connector',
109
+ webhooks: 'Webhook',
110
+ mcp_servers: 'MCP Server',
111
+ knowledge: 'Knowledge Entry',
112
+ plugins: 'Plugin',
113
+ projects: 'Project',
114
+ }
115
+
74
116
  export function AppLayout() {
75
117
  const currentUser = useAppStore((s) => s.currentUser)
76
118
  const sessions = useAppStore((s) => s.sessions)
@@ -133,13 +175,15 @@ export function AppLayout() {
133
175
 
134
176
  const handleShortcutKey = useCallback((e: KeyboardEvent) => {
135
177
  const mod = e.metaKey || e.ctrlKey
136
- // Cmd+N / Ctrl+N — new chat
178
+ // Cmd+N / Ctrl+N — jump to the default agent shortcut
137
179
  if (mod && !e.shiftKey && e.key.toLowerCase() === 'n') {
138
180
  e.preventDefault()
139
181
  const state = useAppStore.getState()
140
- const allAgents = Object.values(state.agents).filter((a) => !a.trashedAt)
141
- const target = allAgents.find((a) => a.id === 'default') || allAgents[0]
142
- if (target) void state.setCurrentAgent(target.id)
182
+ const defaultAgentId = state.appSettings.defaultAgentId && state.agents[state.appSettings.defaultAgentId]
183
+ ? state.appSettings.defaultAgentId
184
+ : Object.values(state.agents)[0]?.id || null
185
+ if (defaultAgentId) void state.setCurrentAgent(defaultAgentId)
186
+ else state.setActiveView('agents')
143
187
  return
144
188
  }
145
189
  // Cmd+Shift+T / Ctrl+Shift+T — jump to tasks
@@ -191,6 +235,17 @@ export function AppLayout() {
191
235
 
192
236
  useWs('plugins', refreshPluginState)
193
237
 
238
+ const isViewEnabled = useCallback((view: AppView) => {
239
+ if (view === 'chatrooms') return plugins['chatroom']?.enabled !== false
240
+ if (view === 'schedules') return plugins['schedule']?.enabled !== false
241
+ if (view === 'memory') return plugins['memory']?.enabled !== false
242
+ if (view === 'connectors') return plugins['connectors']?.enabled !== false
243
+ if (view === 'webhooks') return plugins['http']?.enabled !== false
244
+ if (view === 'wallets') return plugins['wallet']?.enabled !== false
245
+ if (view === 'logs') return plugins['monitor']?.enabled !== false
246
+ return true
247
+ }, [plugins])
248
+
194
249
  const [railExpanded, setRailExpanded] = useState(() => {
195
250
  const stored = safeStorageGet(RAIL_EXPANDED_KEY)
196
251
  return stored === null ? true : stored === 'true'
@@ -237,10 +292,11 @@ export function AppLayout() {
237
292
  const agents = useAppStore((s) => s.agents)
238
293
  const currentAgentId = useAppStore((s) => s.currentAgentId)
239
294
  const setCurrentAgent = useAppStore((s) => s.setCurrentAgent)
240
- const defaultAgentId = appSettings.defaultAgentId && agents[appSettings.defaultAgentId]
241
- ? appSettings.defaultAgentId
242
- : Object.values(agents)[0]?.id || null
243
- const isMainChat = activeView === 'agents' && currentAgentId === defaultAgentId
295
+ const defaultAgent = appSettings.defaultAgentId && agents[appSettings.defaultAgentId]
296
+ ? agents[appSettings.defaultAgentId]
297
+ : Object.values(agents)[0] || null
298
+ const defaultAgentId = defaultAgent?.id || null
299
+ const isDefaultChat = activeView === 'agents' && currentAgentId === defaultAgentId
244
300
 
245
301
  const swipeHandlers = useSwipe({
246
302
  onSwipe: (dir) => {
@@ -255,9 +311,11 @@ export function AppLayout() {
255
311
  const hasCanvas = !!(currentSession?.canvasContent && canvasDismissedFor !== currentSessionId)
256
312
  const canvasAgentName = currentSession?.agentId && agents[currentSession.agentId] ? agents[currentSession.agentId].name : undefined
257
313
 
258
- const goToMainChat = async () => {
314
+ const goToDefaultChat = async () => {
259
315
  if (defaultAgentId) {
260
316
  await setCurrentAgent(defaultAgentId)
317
+ } else {
318
+ setActiveView('agents')
261
319
  }
262
320
  setActiveView('agents')
263
321
  setSidebarOpen(false)
@@ -317,32 +375,60 @@ export function AppLayout() {
317
375
  </div>
318
376
  )}
319
377
 
320
- {/* Main Chat shortcut */}
378
+ {/* Default agent shortcut */}
321
379
  {railExpanded ? (
322
- <div className="px-3 mb-2">
380
+ <div className="px-3 mb-2.5">
323
381
  <button
324
- onClick={goToMainChat}
325
- className={`w-full flex items-center gap-2.5 px-3 py-2.5 rounded-[10px] text-[13px] font-600 cursor-pointer transition-all
326
- ${isMainChat
382
+ onClick={goToDefaultChat}
383
+ className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-[12px] text-[13px] font-600 cursor-pointer transition-all text-left
384
+ ${isDefaultChat
327
385
  ? 'bg-accent-bright/15 border border-[#6366F1]/25 text-accent-bright'
328
386
  : 'bg-accent-bright/10 border border-[#6366F1]/20 text-accent-bright hover:bg-accent-bright/15'}`}
329
387
  style={{ fontFamily: 'inherit' }}
330
388
  >
331
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
332
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
333
- </svg>
334
- Main Chat
389
+ {defaultAgent ? (
390
+ <AgentAvatar
391
+ seed={defaultAgent.avatarSeed || null}
392
+ avatarUrl={defaultAgent.avatarUrl}
393
+ name={defaultAgent.name}
394
+ size={28}
395
+ />
396
+ ) : (
397
+ <div className="w-7 h-7 rounded-full bg-accent-bright/15 flex items-center justify-center shrink-0">
398
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
399
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
400
+ </svg>
401
+ </div>
402
+ )}
403
+ <div className="min-w-0">
404
+ <div className="truncate">{defaultAgent?.name || 'Choose Agent'}</div>
405
+ <div className="text-[10px] font-500 text-accent-bright/75 mt-0.5">
406
+ {defaultAgent ? 'Default shortcut' : 'Pick an agent to open its thread'}
407
+ </div>
408
+ </div>
335
409
  </button>
336
410
  </div>
337
411
  ) : (
338
- <RailTooltip label="Main Chat" description="Your persistent assistant chat">
412
+ <RailTooltip
413
+ label={defaultAgent?.name || 'Choose Agent'}
414
+ description={defaultAgent ? 'Open your default agent shortcut chat' : 'Choose an agent thread'}
415
+ >
339
416
  <button
340
- onClick={goToMainChat}
341
- className={`rail-btn self-center mb-2 ${isMainChat ? 'active' : ''}`}
417
+ onClick={goToDefaultChat}
418
+ className={`rail-btn self-center mb-2 ${isDefaultChat ? 'active' : ''}`}
342
419
  >
343
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
344
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
345
- </svg>
420
+ {defaultAgent ? (
421
+ <AgentAvatar
422
+ seed={defaultAgent.avatarSeed || null}
423
+ avatarUrl={defaultAgent.avatarUrl}
424
+ name={defaultAgent.name}
425
+ size={20}
426
+ />
427
+ ) : (
428
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
429
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
430
+ </svg>
431
+ )}
346
432
  </button>
347
433
  </RailTooltip>
348
434
  )}
@@ -380,128 +466,159 @@ export function AppLayout() {
380
466
 
381
467
  <div className="flex-1 min-h-0 flex flex-col overflow-y-auto overscroll-contain touch-pan-y">
382
468
  {/* Nav items */}
383
- <div className={`flex flex-col gap-0.5 ${railExpanded ? 'px-3' : 'items-center'}`}>
384
- <NavItem view="home" label="Home" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('home')}>
385
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
386
- <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /><polyline points="9 22 9 12 15 12 15 22" />
387
- </svg>
388
- </NavItem>
389
- <NavItem view="agents" label="Agents" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('agents')}>
390
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
391
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
392
- </svg>
393
- </NavItem>
394
- {plugins['chatroom']?.enabled !== false && (
395
- <NavItem view="chatrooms" label="Chatrooms" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('chatrooms')}>
396
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
397
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
398
- <path d="M8 10h8" /><path d="M8 14h4" />
399
- </svg>
400
- </NavItem>
401
- )}
402
- <NavItem view="projects" label="Projects" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('projects')}>
403
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
404
- <path d="M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7-7H4a2 2 0 0 0-2 2v17Z" /><path d="M14 2v7h7" />
405
- </svg>
406
- </NavItem>
407
- {plugins['schedule']?.enabled !== false && (
408
- <NavItem view="schedules" label="Schedules" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('schedules')}>
409
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
410
- <circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
411
- </svg>
412
- </NavItem>
413
- )}
414
- {plugins['memory']?.enabled !== false && (
415
- <NavItem view="memory" label="Memory" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('memory')}>
416
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
417
- <ellipse cx="12" cy="5" rx="9" ry="3" /><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" /><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
418
- </svg>
419
- </NavItem>
420
- )}
421
- <NavItem view="tasks" label="Tasks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('tasks')} badge={pendingApprovalCount}>
422
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
423
- <path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" /><rect x="9" y="3" width="6" height="4" rx="1" /><path d="M9 14l2 2 4-4" />
424
- </svg>
425
- </NavItem>
426
- <NavItem view="approvals" label="Approvals" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('approvals')} badge={pendingApprovalCount}>
427
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
428
- <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
429
- <path d="m9 12 2 2 4-4"/>
430
- </svg>
431
- </NavItem>
432
- <NavItem view="secrets" label="Secrets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('secrets')}>
433
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
434
- <rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
435
- </svg>
436
- </NavItem>
437
- <NavItem view="providers" label="Providers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('providers')}>
438
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
439
- <path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" />
440
- </svg>
441
- </NavItem>
442
- <NavItem view="skills" label="Skills" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('skills')}>
443
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
444
- <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
445
- </svg>
446
- </NavItem>
447
- {plugins['connectors']?.enabled !== false && (
448
- <NavItem view="connectors" label="Connectors" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('connectors')}>
449
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
450
- <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3" /><line x1="8" y1="12" x2="16" y2="12" />
451
- </svg>
452
- </NavItem>
453
- )}
454
- {plugins['http']?.enabled !== false && (
455
- <NavItem view="webhooks" label="Webhooks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('webhooks')}>
456
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
457
- <path d="M22 12h-4l-3 7L9 5l-3 7H2" />
458
- </svg>
459
- </NavItem>
460
- )}
461
- <NavItem view="mcp_servers" label="MCP" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('mcp_servers')}>
462
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
463
- <rect x="2" y="2" width="20" height="8" rx="2" /><rect x="2" y="14" width="20" height="8" rx="2" /><line x1="6" y1="6" x2="6.01" y2="6" /><line x1="6" y1="18" x2="6.01" y2="18" />
464
- </svg>
465
- </NavItem>
466
- <NavItem view="knowledge" label="Knowledge" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('knowledge')}>
467
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
468
- <circle cx="12" cy="12" r="10" /><line x1="2" y1="12" x2="22" y2="12" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
469
- </svg>
470
- </NavItem>
471
- <NavItem view="plugins" label="Plugins" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('plugins')}>
472
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
473
- <path d="M12 2v4m0 12v4M2 12h4m12 0h4" /><circle cx="12" cy="12" r="4" /><path d="M8 8L5.5 5.5M16 8l2.5-2.5M8 16l-2.5 2.5M16 16l2.5 2.5" />
474
- </svg>
475
- </NavItem>
476
- <NavItem view="usage" label="Usage" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('usage')}>
477
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
478
- <line x1="18" y1="20" x2="18" y2="10" /><line x1="12" y1="20" x2="12" y2="4" /><line x1="6" y1="20" x2="6" y2="14" />
479
- </svg>
480
- </NavItem>
481
- {plugins['wallet']?.enabled !== false && (
482
- <NavItem view="wallets" label="Wallets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('wallets')}>
483
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
484
- <rect x="2" y="6" width="20" height="14" rx="2" /><path d="M22 10H18a2 2 0 0 0 0 4h4" /><path d="M6 6V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v2" />
485
- </svg>
486
- </NavItem>
487
- )}
488
- <NavItem view="runs" label="Runs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('runs')}>
489
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
490
- <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
491
- </svg>
492
- </NavItem>
493
- <NavItem view="activity" label="Activity" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('activity')}>
494
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
495
- <path d="M12 8v4l3 3" /><circle cx="12" cy="12" r="10" />
496
- </svg>
497
- </NavItem>
498
- {plugins['monitor']?.enabled !== false && (
499
- <NavItem view="logs" label="Logs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('logs')}>
500
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
501
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" />
502
- </svg>
503
- </NavItem>
504
- )}
469
+ <div className={`flex flex-col gap-3 ${railExpanded ? 'px-3' : 'items-center'}`}>
470
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
471
+ {railExpanded ? (
472
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Workspace</div>
473
+ ) : (
474
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
475
+ )}
476
+ <NavItem view="home" label="Home" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('home')}>
477
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
478
+ <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /><polyline points="9 22 9 12 15 12 15 22" />
479
+ </svg>
480
+ </NavItem>
481
+ <NavItem view="agents" label="Agents" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('agents')}>
482
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
483
+ <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
484
+ </svg>
485
+ </NavItem>
486
+ {isViewEnabled('chatrooms') && (
487
+ <NavItem view="chatrooms" label="Chatrooms" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('chatrooms')}>
488
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
489
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
490
+ <path d="M8 10h8" /><path d="M8 14h4" />
491
+ </svg>
492
+ </NavItem>
493
+ )}
494
+ <NavItem view="projects" label="Projects" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('projects')}>
495
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
496
+ <path d="M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7-7H4a2 2 0 0 0-2 2v17Z" /><path d="M14 2v7h7" />
497
+ </svg>
498
+ </NavItem>
499
+ </div>
500
+
501
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
502
+ {railExpanded ? (
503
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Execution</div>
504
+ ) : (
505
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
506
+ )}
507
+ <NavItem view="tasks" label="Tasks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('tasks')} badge={pendingApprovalCount}>
508
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
509
+ <path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" /><rect x="9" y="3" width="6" height="4" rx="1" /><path d="M9 14l2 2 4-4" />
510
+ </svg>
511
+ </NavItem>
512
+ <NavItem view="approvals" label="Approvals" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('approvals')} badge={pendingApprovalCount}>
513
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
514
+ <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
515
+ <path d="m9 12 2 2 4-4"/>
516
+ </svg>
517
+ </NavItem>
518
+ {isViewEnabled('schedules') && (
519
+ <NavItem view="schedules" label="Schedules" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('schedules')}>
520
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
521
+ <circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
522
+ </svg>
523
+ </NavItem>
524
+ )}
525
+ {isViewEnabled('memory') && (
526
+ <NavItem view="memory" label="Memory" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('memory')}>
527
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
528
+ <ellipse cx="12" cy="5" rx="9" ry="3" /><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" /><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
529
+ </svg>
530
+ </NavItem>
531
+ )}
532
+ <NavItem view="runs" label="Runs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('runs')}>
533
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
534
+ <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
535
+ </svg>
536
+ </NavItem>
537
+ </div>
538
+
539
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
540
+ {railExpanded ? (
541
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Knowledge</div>
542
+ ) : (
543
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
544
+ )}
545
+ <NavItem view="knowledge" label="Knowledge" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('knowledge')}>
546
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
547
+ <circle cx="12" cy="12" r="10" /><line x1="2" y1="12" x2="22" y2="12" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
548
+ </svg>
549
+ </NavItem>
550
+ <NavItem view="skills" label="Skills" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('skills')}>
551
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
552
+ <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
553
+ </svg>
554
+ </NavItem>
555
+ {isViewEnabled('connectors') && (
556
+ <NavItem view="connectors" label="Connectors" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('connectors')}>
557
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
558
+ <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3" /><line x1="8" y1="12" x2="16" y2="12" />
559
+ </svg>
560
+ </NavItem>
561
+ )}
562
+ {isViewEnabled('webhooks') && (
563
+ <NavItem view="webhooks" label="Webhooks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('webhooks')}>
564
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
565
+ <path d="M22 12h-4l-3 7L9 5l-3 7H2" />
566
+ </svg>
567
+ </NavItem>
568
+ )}
569
+ <NavItem view="mcp_servers" label="MCP Servers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('mcp_servers')}>
570
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
571
+ <rect x="2" y="2" width="20" height="8" rx="2" /><rect x="2" y="14" width="20" height="8" rx="2" /><line x1="6" y1="6" x2="6.01" y2="6" /><line x1="6" y1="18" x2="6.01" y2="18" />
572
+ </svg>
573
+ </NavItem>
574
+ <NavItem view="plugins" label="Plugins" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('plugins')}>
575
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
576
+ <path d="M12 2v4m0 12v4M2 12h4m12 0h4" /><circle cx="12" cy="12" r="4" /><path d="M8 8L5.5 5.5M16 8l2.5-2.5M8 16l-2.5 2.5M16 16l2.5 2.5" />
577
+ </svg>
578
+ </NavItem>
579
+ </div>
580
+
581
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
582
+ {railExpanded ? (
583
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">System</div>
584
+ ) : (
585
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
586
+ )}
587
+ <NavItem view="secrets" label="Secrets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('secrets')}>
588
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
589
+ <rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
590
+ </svg>
591
+ </NavItem>
592
+ <NavItem view="providers" label="Providers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('providers')}>
593
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
594
+ <path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" />
595
+ </svg>
596
+ </NavItem>
597
+ <NavItem view="usage" label="Usage" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('usage')}>
598
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
599
+ <line x1="18" y1="20" x2="18" y2="10" /><line x1="12" y1="20" x2="12" y2="4" /><line x1="6" y1="20" x2="6" y2="14" />
600
+ </svg>
601
+ </NavItem>
602
+ <NavItem view="activity" label="Activity" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('activity')}>
603
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
604
+ <path d="M12 8v4l3 3" /><circle cx="12" cy="12" r="10" />
605
+ </svg>
606
+ </NavItem>
607
+ {isViewEnabled('wallets') && (
608
+ <NavItem view="wallets" label="Wallets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('wallets')}>
609
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
610
+ <rect x="2" y="6" width="20" height="14" rx="2" /><path d="M22 10H18a2 2 0 0 0 0 4h4" /><path d="M6 6V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v2" />
611
+ </svg>
612
+ </NavItem>
613
+ )}
614
+ {isViewEnabled('logs') && (
615
+ <NavItem view="logs" label="Logs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('logs')}>
616
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
617
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" />
618
+ </svg>
619
+ </NavItem>
620
+ )}
621
+ </div>
505
622
  </div>
506
623
 
507
624
  <div className="flex-1" />
@@ -616,7 +733,7 @@ export function AppLayout() {
616
733
  style={{ animation: 'panel-in 0.3s var(--ease-spring)' }}
617
734
  >
618
735
  <div className="flex items-center px-5 pt-5 pb-3 shrink-0">
619
- <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] capitalize flex-1">{activeView}</h2>
736
+ <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] flex-1">{VIEW_LABELS[activeView]}</h2>
620
737
  {activeView === 'logs' || activeView === 'usage' || activeView === 'runs' ? null : activeView === 'memory' ? (
621
738
  <button
622
739
  onClick={() => useAppStore.getState().setMemorySheetOpen(true)}
@@ -638,7 +755,7 @@ export function AppLayout() {
638
755
  <line x1="12" y1="5" x2="12" y2="19" />
639
756
  <line x1="5" y1="12" x2="19" y2="12" />
640
757
  </svg>
641
- {activeView === 'agents' ? 'Agent' : activeView === 'schedules' ? 'Schedule' : activeView === 'tasks' ? 'Task' : activeView === 'secrets' ? 'Secret' : activeView === 'providers' ? 'Provider' : activeView === 'skills' ? 'Skill' : activeView === 'connectors' ? 'Connector' : activeView === 'webhooks' ? 'Webhook' : activeView === 'mcp_servers' ? 'MCP Server' : activeView === 'knowledge' ? 'Knowledge' : 'New'}
758
+ {CREATE_LABELS[activeView] || 'New'}
642
759
  </button>
643
760
  )}
644
761
  </div>
@@ -706,32 +823,89 @@ export function AppLayout() {
706
823
  <Avatar user={currentUser!} size="sm" avatarSeed={appSettings.userAvatarSeed} />
707
824
  </button>
708
825
  </div>
709
- {/* View selector tabs */}
710
- <div className="flex px-4 py-2 gap-1 shrink-0 flex-wrap">
711
- {(['agents', 'chatrooms', 'schedules', 'memory', 'tasks', 'secrets', 'providers', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'knowledge', 'plugins', 'usage', 'runs', 'logs'] as AppView[]).map((v) => (
712
- <button
713
- key={v}
714
- onClick={() => setActiveView(v)}
715
- className={`py-2 px-2.5 rounded-[10px] text-[11px] font-600 capitalize cursor-pointer transition-all
716
- ${activeView === v
717
- ? 'bg-accent-soft text-accent-bright'
718
- : 'bg-transparent text-text-3 hover:text-text-2'}`}
719
- style={{ fontFamily: 'inherit' }}
720
- >
721
- {v}
722
- </button>
723
- ))}
724
- {/* Dynamic Plugin Items */}
725
- {pluginSidebarItems.map((item) => (
826
+ {defaultAgent && (
827
+ <div className="px-4 pt-1 pb-3 shrink-0">
726
828
  <button
727
- key={item.id}
728
- onClick={() => window.open(item.href, '_blank')}
729
- className="py-2 px-2.5 rounded-[10px] text-[11px] font-600 capitalize cursor-pointer transition-all bg-emerald-500/[0.05] text-emerald-400/80 hover:text-emerald-400 border border-emerald-400/10"
829
+ onClick={goToDefaultChat}
830
+ className={`w-full flex items-center gap-3 rounded-[14px] border px-4 py-3 text-left transition-all cursor-pointer ${
831
+ isDefaultChat
832
+ ? 'bg-accent-soft border-accent-bright/25 text-accent-bright'
833
+ : 'bg-accent-soft/50 border-accent-bright/15 text-accent-bright hover:bg-accent-soft/65'
834
+ }`}
730
835
  style={{ fontFamily: 'inherit' }}
731
836
  >
732
- {item.label}
837
+ <AgentAvatar
838
+ seed={defaultAgent.avatarSeed || null}
839
+ avatarUrl={defaultAgent.avatarUrl}
840
+ name={defaultAgent.name}
841
+ size={32}
842
+ />
843
+ <div className="min-w-0">
844
+ <div className="text-[13px] font-700 truncate">{defaultAgent.name}</div>
845
+ <div className="text-[11px] text-accent-bright/70">Default shortcut</div>
846
+ </div>
733
847
  </button>
734
- ))}
848
+ </div>
849
+ )}
850
+ <div className="px-4 pb-3 shrink-0 max-h-[260px] overflow-y-auto">
851
+ <div className="space-y-4">
852
+ {([
853
+ { label: 'Workspace', views: ['agents', 'chatrooms', 'projects'] as AppView[] },
854
+ { label: 'Execution', views: ['tasks', 'approvals', 'schedules', 'memory', 'runs'] as AppView[] },
855
+ { label: 'Knowledge', views: ['knowledge', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'plugins'] as AppView[] },
856
+ { label: 'System', views: ['secrets', 'providers', 'usage', 'logs'] as AppView[] },
857
+ ]).map((section) => {
858
+ const visibleViews = section.views.filter((view) => isViewEnabled(view))
859
+ if (!visibleViews.length) return null
860
+ return (
861
+ <div key={section.label}>
862
+ <div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
863
+ {section.label}
864
+ </div>
865
+ <div className="grid grid-cols-2 gap-2">
866
+ {visibleViews.map((view) => (
867
+ <button
868
+ key={view}
869
+ onClick={() => {
870
+ setActiveView(view)
871
+ if (FULL_WIDTH_VIEWS.has(view)) setSidebarOpen(false)
872
+ }}
873
+ className={`rounded-[12px] border px-3 py-2.5 text-left transition-all cursor-pointer ${
874
+ activeView === view
875
+ ? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
876
+ : 'bg-transparent border-white/[0.06] text-text-3 hover:text-text hover:bg-white/[0.04]'
877
+ }`}
878
+ style={{ fontFamily: 'inherit' }}
879
+ >
880
+ <div className="text-[12px] font-600">{VIEW_LABELS[view]}</div>
881
+ <div className="text-[10px] text-current/60 mt-1">{VIEW_DESCRIPTIONS[view]}</div>
882
+ </button>
883
+ ))}
884
+ </div>
885
+ </div>
886
+ )
887
+ })}
888
+ {pluginSidebarItems.length > 0 && (
889
+ <div>
890
+ <div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
891
+ Extensions
892
+ </div>
893
+ <div className="grid grid-cols-2 gap-2">
894
+ {pluginSidebarItems.map((item) => (
895
+ <button
896
+ key={item.id}
897
+ onClick={() => window.open(item.href, '_blank')}
898
+ className="rounded-[12px] border border-emerald-400/10 bg-emerald-500/[0.05] px-3 py-2.5 text-left text-emerald-400/85 hover:text-emerald-300 transition-colors cursor-pointer"
899
+ style={{ fontFamily: 'inherit' }}
900
+ >
901
+ <div className="text-[12px] font-600">{item.label}</div>
902
+ <div className="text-[10px] text-emerald-300/60 mt-1">Open plugin view</div>
903
+ </button>
904
+ ))}
905
+ </div>
906
+ </div>
907
+ )}
908
+ </div>
735
909
  </div>
736
910
  {activeView !== 'logs' && activeView !== 'usage' && activeView !== 'runs' && activeView !== 'settings' && (
737
911
  <div className="px-4 py-2.5 shrink-0">
@@ -745,7 +919,7 @@ export function AppLayout() {
745
919
  shadow-[0_2px_12px_rgba(99,102,241,0.15)]"
746
920
  style={{ fontFamily: 'inherit' }}
747
921
  >
748
- + New {activeView === 'agents' ? 'Agent' : activeView === 'schedules' ? 'Schedule' : activeView === 'tasks' ? 'Task' : activeView === 'secrets' ? 'Secret' : activeView === 'providers' ? 'Provider' : activeView === 'skills' ? 'Skill' : activeView === 'connectors' ? 'Connector' : activeView === 'webhooks' ? 'Webhook' : activeView === 'mcp_servers' ? 'MCP Server' : activeView === 'knowledge' ? 'Knowledge' : activeView === 'plugins' ? 'Plugin' : activeView === 'projects' ? 'Project' : 'Entry'}
922
+ + New {CREATE_LABELS[activeView] || 'Entry'}
749
923
  </button>
750
924
  </div>
751
925
  )}
@@ -811,11 +985,27 @@ export function AppLayout() {
811
985
  <div className="flex-1 flex items-center justify-center px-8">
812
986
  <div className="text-center max-w-[420px]">
813
987
  <h2 className="font-display text-[24px] font-700 text-text mb-2 tracking-[-0.02em]">
814
- Select an Agent
988
+ Open a Chat
815
989
  </h2>
816
990
  <p className="text-[14px] text-text-3">
817
- Choose an agent from the sidebar to start chatting.
991
+ Choose a chat from the sidebar, or jump straight into your default agent shortcut.
818
992
  </p>
993
+ <div className="mt-5 flex items-center justify-center gap-3">
994
+ <button
995
+ onClick={defaultAgent ? goToDefaultChat : () => setAgentSheetOpen(true)}
996
+ className="inline-flex items-center gap-2 px-4 py-2.5 rounded-[12px] border-none bg-accent-bright text-white text-[13px] font-600 cursor-pointer hover:brightness-110 transition-all"
997
+ style={{ fontFamily: 'inherit' }}
998
+ >
999
+ {defaultAgent ? `Open ${defaultAgent.name}` : 'Create Agent'}
1000
+ </button>
1001
+ <button
1002
+ onClick={() => setAgentSheetOpen(true)}
1003
+ className="inline-flex items-center gap-2 px-4 py-2.5 rounded-[12px] border border-white/[0.08] bg-transparent text-[13px] font-600 text-text-2 cursor-pointer hover:bg-white/[0.04] transition-all"
1004
+ style={{ fontFamily: 'inherit' }}
1005
+ >
1006
+ Create Agent
1007
+ </button>
1008
+ </div>
819
1009
  </div>
820
1010
  </div>
821
1011
  )}
@@ -865,7 +1055,7 @@ export function AppLayout() {
865
1055
  <div className="flex-1 flex flex-col h-full">
866
1056
  <div className="flex items-center px-6 pt-5 pb-3 shrink-0">
867
1057
  <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] capitalize flex-1">
868
- {activeView === 'mcp_servers' ? 'MCP Servers' : activeView.replace('_', ' ')}
1058
+ {VIEW_LABELS[activeView]}
869
1059
  </h2>
870
1060
  {activeView !== 'runs' && activeView !== 'logs' && (
871
1061
  <button
@@ -876,7 +1066,7 @@ export function AppLayout() {
876
1066
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
877
1067
  <line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
878
1068
  </svg>
879
- {activeView === 'schedules' ? 'Schedule' : activeView === 'secrets' ? 'Secret' : activeView === 'providers' ? 'Provider' : activeView === 'skills' ? 'Skill' : activeView === 'connectors' ? 'Connector' : activeView === 'webhooks' ? 'Webhook' : activeView === 'mcp_servers' ? 'MCP Server' : activeView === 'knowledge' ? 'Knowledge' : activeView === 'plugins' ? 'Plugin' : 'New'}
1069
+ {CREATE_LABELS[activeView] || 'New'}
880
1070
  </button>
881
1071
  )}
882
1072
  </div>
@@ -908,6 +1098,7 @@ export function AppLayout() {
908
1098
  <TaskSheet />
909
1099
  <SecretSheet />
910
1100
  <ProviderSheet />
1101
+ <GatewaySheet />
911
1102
  <SkillSheet />
912
1103
  <ConnectorSheet />
913
1104
  <ChatroomSheet />
@@ -981,9 +1172,9 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
981
1172
  chatrooms: 'Multi-agent collaborative chatrooms',
982
1173
  schedules: 'Automated task schedules',
983
1174
  memory: 'Long-term agent memory store',
984
- tasks: 'Task board for orchestrator jobs',
1175
+ tasks: 'Task board for agent work and queued runs',
985
1176
  approvals: 'Pending tool execution approvals',
986
- secrets: 'API keys & credentials for orchestrators',
1177
+ secrets: 'API keys, tokens, and encrypted credentials',
987
1178
  providers: 'LLM providers & custom endpoints',
988
1179
  skills: 'Reusable instruction sets for agents',
989
1180
  connectors: 'Chat platform bridges (Discord, Slack, etc.)',
@@ -995,7 +1186,7 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
995
1186
  usage: 'Usage metrics, cost tracking & agent performance',
996
1187
  wallets: 'Agent crypto wallets — hold funds, send SOL, manage spending',
997
1188
  runs: 'Live run monitoring & history',
998
- settings: 'Manage providers, API keys & orchestrator engine',
1189
+ settings: 'Manage defaults, providers, secrets, and automation settings',
999
1190
  projects: 'Group agents, tasks & schedules into projects',
1000
1191
  activity: 'Audit trail of all entity mutations',
1001
1192
  }
@@ -1016,26 +1207,26 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1016
1207
  schedules: {
1017
1208
  icon: 'clock',
1018
1209
  title: 'Schedules',
1019
- description: 'Automate recurring tasks by scheduling orchestrators to run on a cron, interval, or one-time basis.',
1020
- features: ['Set up cron expressions for precise timing', 'Run orchestrators automatically on intervals', 'Schedule one-time future tasks', 'View execution history and results'],
1210
+ description: 'Automate recurring work with cron, interval, or one-time schedules that launch agent tasks.',
1211
+ features: ['Set up cron expressions for precise timing', 'Run agents automatically on intervals', 'Schedule one-time future tasks', 'View execution history and results'],
1021
1212
  },
1022
1213
  memory: {
1023
1214
  icon: 'database',
1024
1215
  title: 'Memory',
1025
- description: 'Long-term memory store for AI agents. Orchestrators can store and retrieve knowledge across conversations.',
1216
+ description: 'Long-term memory store for AI agents so they can retain useful context across conversations.',
1026
1217
  features: ['Agents store findings and learnings automatically', 'Full-text search across all stored memories', 'Organized by categories and agents', 'Persists across conversations for continuity'],
1027
1218
  },
1028
1219
  tasks: {
1029
1220
  icon: 'clipboard',
1030
1221
  title: 'Task Board',
1031
- description: 'A Trello-style board for managing orchestrator jobs. Create tasks, assign them to orchestrators, and track progress.',
1032
- features: ['Kanban columns: Backlog, Queued, Running, Completed, Failed', 'Assign tasks to specific orchestrator agents', 'Sequential queue ensures orchestrators don\'t conflict', 'View results and logs for completed tasks'],
1222
+ description: 'A kanban board for managing agent work. Create tasks, assign them to agents, and track progress.',
1223
+ features: ['Kanban columns: Backlog, Queued, Running, Completed, Failed', 'Assign tasks to specific agents', 'Track retries, results, and logs', 'Review status without leaving the board'],
1033
1224
  },
1034
1225
  secrets: {
1035
1226
  icon: 'lock',
1036
1227
  title: 'Secrets',
1037
- description: 'Manage API keys and credentials that orchestrators can access during task execution.',
1038
- features: ['Store keys for external services (Gmail, APIs, etc.)', 'Scope secrets globally or to specific orchestrators', 'Encrypted at rest with AES-256-GCM', 'Orchestrators retrieve secrets via the get_secret tool'],
1228
+ description: 'Manage API keys and credentials that agents and integrations can access securely.',
1229
+ features: ['Store keys for external services (Gmail, APIs, etc.)', 'Scope secrets globally or to specific agents', 'Encrypted at rest with AES-256-GCM', 'Agents retrieve secrets through approved tools'],
1039
1230
  },
1040
1231
  providers: {
1041
1232
  icon: 'zap',
@@ -1058,8 +1249,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1058
1249
  webhooks: {
1059
1250
  icon: 'webhook',
1060
1251
  title: 'Webhooks',
1061
- description: 'Receive external events over HTTP and trigger orchestrator runs automatically.',
1062
- features: ['Create secure inbound webhook endpoints', 'Filter events by type or source', 'Route each webhook to a specific orchestrator', 'Use x-webhook-secret for request authentication'],
1252
+ description: 'Receive external events over HTTP and route them into agent-driven workflows automatically.',
1253
+ features: ['Create secure inbound webhook endpoints', 'Filter events by type or source', 'Route each webhook to a specific agent', 'Use x-webhook-secret for request authentication'],
1063
1254
  },
1064
1255
  mcp_servers: {
1065
1256
  icon: 'server',
@@ -1070,7 +1261,7 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1070
1261
  knowledge: {
1071
1262
  icon: 'globe',
1072
1263
  title: 'Knowledge Base',
1073
- description: 'A shared knowledge graph accessible by all agents, enabling cross-agent information sharing and orchestration.',
1264
+ description: 'A shared knowledge graph accessible by all agents for cross-workspace information sharing.',
1074
1265
  features: ['Create tagged knowledge entries', 'Agents can store and search knowledge via tools', 'Full-text and vector search', 'Provenance tracking per entry'],
1075
1266
  },
1076
1267
  logs: {
@@ -1100,8 +1291,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1100
1291
  settings: {
1101
1292
  icon: 'settings',
1102
1293
  title: 'Settings',
1103
- description: 'Manage providers, API keys & orchestrator engine.',
1104
- features: ['Configure LLM providers', 'Manage API credentials', 'Tune orchestrator settings', 'Set up voice & embedding'],
1294
+ description: 'Manage app defaults, providers, encrypted secrets, and automation settings.',
1295
+ features: ['Choose your default agent shortcut', 'Configure LLM providers and credentials', 'Tune heartbeat and autonomy settings', 'Set up voice, embeddings, and search'],
1105
1296
  },
1106
1297
  projects: {
1107
1298
  icon: 'folder',
@@ -1283,7 +1474,7 @@ function RailTooltip({ label, description, children }: { label: string; descript
1283
1474
  }
1284
1475
 
1285
1476
  function DesktopEmptyState({ userName }: { userName: string | null }) {
1286
- const setNewSessionOpen = useAppStore((s) => s.setNewSessionOpen)
1477
+ const setAgentSheetOpen = useAppStore((s) => s.setAgentSheetOpen)
1287
1478
 
1288
1479
  return (
1289
1480
  <div className="flex-1 flex flex-col items-center justify-center px-8 pb-20 relative overflow-hidden">
@@ -1314,10 +1505,10 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
1314
1505
  <span className="text-text-2">What would you like to do?</span>
1315
1506
  </h1>
1316
1507
  <p className="text-[15px] text-text-3 mb-12">
1317
- Create a new chat to start chatting
1508
+ Create an agent, then keep working in its persistent thread
1318
1509
  </p>
1319
1510
  <button
1320
- onClick={() => setNewSessionOpen(true)}
1511
+ onClick={() => setAgentSheetOpen(true)}
1321
1512
  className="inline-flex items-center gap-2.5 px-12 py-4 rounded-[16px] border-none bg-accent-bright text-white text-[16px] font-display font-600
1322
1513
  cursor-pointer hover:brightness-110 active:scale-[0.97] transition-all duration-200
1323
1514
  shadow-[0_6px_28px_rgba(99,102,241,0.3)]"
@@ -1327,7 +1518,7 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
1327
1518
  <line x1="12" y1="5" x2="12" y2="19" />
1328
1519
  <line x1="5" y1="12" x2="19" y2="12" />
1329
1520
  </svg>
1330
- New Chat
1521
+ New Agent
1331
1522
  </button>
1332
1523
  </div>
1333
1524
  </div>