@swarmclawai/swarmclaw 0.7.1 → 0.7.3

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 (237) hide show
  1. package/README.md +155 -150
  2. package/package.json +1 -1
  3. package/src/app/api/agents/[id]/route.ts +26 -0
  4. package/src/app/api/agents/[id]/thread/route.ts +37 -9
  5. package/src/app/api/agents/route.ts +13 -2
  6. package/src/app/api/auth/route.ts +76 -7
  7. package/src/app/api/chatrooms/[id]/chat/route.ts +7 -2
  8. package/src/app/api/{sessions → chats}/[id]/browser/route.ts +5 -1
  9. package/src/app/api/{sessions → chats}/[id]/chat/route.ts +7 -3
  10. package/src/app/api/{sessions → chats}/[id]/checkpoints/route.ts +1 -1
  11. package/src/app/api/chats/[id]/main-loop/route.ts +13 -0
  12. package/src/app/api/{sessions → chats}/[id]/messages/route.ts +19 -13
  13. package/src/app/api/{sessions → chats}/[id]/restore/route.ts +1 -1
  14. package/src/app/api/{sessions → chats}/[id]/route.ts +22 -52
  15. package/src/app/api/{sessions → chats}/[id]/stop/route.ts +6 -1
  16. package/src/app/api/{sessions → chats}/route.ts +21 -7
  17. package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
  18. package/src/app/api/connectors/doctor/route.ts +13 -0
  19. package/src/app/api/files/open/route.ts +16 -14
  20. package/src/app/api/memory/maintenance/route.ts +11 -1
  21. package/src/app/api/openclaw/agent-files/route.ts +27 -4
  22. package/src/app/api/openclaw/skills/route.ts +11 -3
  23. package/src/app/api/plugins/dependencies/route.ts +24 -0
  24. package/src/app/api/plugins/install/route.ts +15 -92
  25. package/src/app/api/plugins/route.ts +6 -26
  26. package/src/app/api/plugins/settings/route.ts +40 -0
  27. package/src/app/api/plugins/ui/route.ts +1 -0
  28. package/src/app/api/settings/route.ts +49 -7
  29. package/src/app/api/tasks/[id]/route.ts +15 -6
  30. package/src/app/api/tasks/bulk/route.ts +2 -2
  31. package/src/app/api/tasks/route.ts +9 -4
  32. package/src/app/api/usage/route.ts +30 -0
  33. package/src/app/api/webhooks/[id]/route.ts +8 -1
  34. package/src/app/page.tsx +9 -2
  35. package/src/cli/index.js +39 -33
  36. package/src/cli/index.ts +43 -49
  37. package/src/cli/spec.js +29 -27
  38. package/src/components/agents/agent-card.tsx +16 -13
  39. package/src/components/agents/agent-chat-list.tsx +104 -4
  40. package/src/components/agents/agent-list.tsx +54 -22
  41. package/src/components/agents/agent-sheet.tsx +209 -18
  42. package/src/components/agents/cron-job-form.tsx +3 -3
  43. package/src/components/agents/inspector-panel.tsx +110 -50
  44. package/src/components/auth/access-key-gate.tsx +36 -97
  45. package/src/components/auth/setup-wizard.tsx +5 -38
  46. package/src/components/chat/chat-area.tsx +39 -27
  47. package/src/components/{sessions/session-card.tsx → chat/chat-card.tsx} +7 -23
  48. package/src/components/chat/chat-header.tsx +299 -314
  49. package/src/components/{sessions/session-list.tsx → chat/chat-list.tsx} +11 -14
  50. package/src/components/chat/chat-tool-toggles.tsx +26 -17
  51. package/src/components/chat/checkpoint-timeline.tsx +4 -4
  52. package/src/components/chat/message-bubble.tsx +4 -1
  53. package/src/components/chat/message-list.tsx +5 -3
  54. package/src/components/chat/session-debug-panel.tsx +1 -1
  55. package/src/components/chat/tool-request-banner.tsx +3 -3
  56. package/src/components/chatrooms/agent-hover-card.tsx +3 -3
  57. package/src/components/chatrooms/chatroom-tool-request-banner.tsx +2 -2
  58. package/src/components/chatrooms/chatroom-view.tsx +347 -205
  59. package/src/components/connectors/connector-list.tsx +265 -127
  60. package/src/components/connectors/connector-sheet.tsx +218 -1
  61. package/src/components/home/home-view.tsx +129 -5
  62. package/src/components/layout/app-layout.tsx +392 -182
  63. package/src/components/layout/mobile-header.tsx +26 -8
  64. package/src/components/plugins/plugin-list.tsx +487 -254
  65. package/src/components/plugins/plugin-sheet.tsx +236 -13
  66. package/src/components/projects/project-detail.tsx +183 -0
  67. package/src/components/settings/gateway-connection-panel.tsx +1 -1
  68. package/src/components/shared/agent-picker-list.tsx +2 -2
  69. package/src/components/shared/command-palette.tsx +111 -25
  70. package/src/components/shared/settings/plugin-manager.tsx +20 -4
  71. package/src/components/shared/settings/section-capability-policy.tsx +105 -0
  72. package/src/components/shared/settings/section-heartbeat.tsx +78 -1
  73. package/src/components/shared/settings/section-orchestrator.tsx +3 -3
  74. package/src/components/shared/settings/section-providers.tsx +1 -1
  75. package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
  76. package/src/components/shared/settings/section-secrets.tsx +6 -6
  77. package/src/components/shared/settings/section-user-preferences.tsx +1 -1
  78. package/src/components/shared/settings/section-voice.tsx +5 -1
  79. package/src/components/shared/settings/section-web-search.tsx +10 -2
  80. package/src/components/shared/settings/settings-page.tsx +244 -56
  81. package/src/components/tasks/approvals-panel.tsx +205 -18
  82. package/src/components/tasks/task-board.tsx +242 -46
  83. package/src/components/usage/metrics-dashboard.tsx +147 -1
  84. package/src/components/wallets/wallet-panel.tsx +17 -5
  85. package/src/components/webhooks/webhook-sheet.tsx +8 -8
  86. package/src/lib/auth.ts +17 -0
  87. package/src/lib/chat-streaming-state.test.ts +108 -0
  88. package/src/lib/chat-streaming-state.ts +108 -0
  89. package/src/lib/chat.ts +1 -1
  90. package/src/lib/{sessions.ts → chats.ts} +28 -18
  91. package/src/lib/openclaw-agent-id.test.ts +14 -0
  92. package/src/lib/openclaw-agent-id.ts +31 -0
  93. package/src/lib/providers/claude-cli.ts +1 -1
  94. package/src/lib/server/agent-assignment.test.ts +112 -0
  95. package/src/lib/server/agent-assignment.ts +169 -0
  96. package/src/lib/server/approval-connector-notify.test.ts +253 -0
  97. package/src/lib/server/approvals-auto-approve.test.ts +205 -0
  98. package/src/lib/server/approvals.ts +483 -75
  99. package/src/lib/server/autonomy-runtime.test.ts +341 -0
  100. package/src/lib/server/browser-state.test.ts +118 -0
  101. package/src/lib/server/browser-state.ts +123 -0
  102. package/src/lib/server/build-llm.test.ts +36 -0
  103. package/src/lib/server/build-llm.ts +11 -4
  104. package/src/lib/server/builtin-plugins.ts +34 -0
  105. package/src/lib/server/capability-router.ts +10 -8
  106. package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
  107. package/src/lib/server/chat-execution-tool-events.test.ts +134 -0
  108. package/src/lib/server/chat-execution.ts +285 -165
  109. package/src/lib/server/chatroom-health.test.ts +26 -0
  110. package/src/lib/server/chatroom-health.ts +2 -3
  111. package/src/lib/server/chatroom-helpers.test.ts +67 -2
  112. package/src/lib/server/chatroom-helpers.ts +48 -8
  113. package/src/lib/server/connectors/discord.ts +175 -11
  114. package/src/lib/server/connectors/doctor.test.ts +80 -0
  115. package/src/lib/server/connectors/doctor.ts +116 -0
  116. package/src/lib/server/connectors/manager.ts +948 -112
  117. package/src/lib/server/connectors/policy.test.ts +222 -0
  118. package/src/lib/server/connectors/policy.ts +452 -0
  119. package/src/lib/server/connectors/slack.ts +188 -9
  120. package/src/lib/server/connectors/telegram.ts +65 -15
  121. package/src/lib/server/connectors/thread-context.test.ts +44 -0
  122. package/src/lib/server/connectors/thread-context.ts +72 -0
  123. package/src/lib/server/connectors/types.ts +41 -11
  124. package/src/lib/server/cost.ts +34 -1
  125. package/src/lib/server/daemon-state.ts +61 -3
  126. package/src/lib/server/data-dir.ts +13 -0
  127. package/src/lib/server/delegation-jobs.test.ts +140 -0
  128. package/src/lib/server/delegation-jobs.ts +248 -0
  129. package/src/lib/server/document-utils.test.ts +47 -0
  130. package/src/lib/server/document-utils.ts +397 -0
  131. package/src/lib/server/heartbeat-service.ts +14 -40
  132. package/src/lib/server/heartbeat-source.test.ts +22 -0
  133. package/src/lib/server/heartbeat-source.ts +7 -0
  134. package/src/lib/server/identity-continuity.test.ts +77 -0
  135. package/src/lib/server/identity-continuity.ts +127 -0
  136. package/src/lib/server/mailbox-utils.ts +347 -0
  137. package/src/lib/server/main-agent-loop.ts +28 -1103
  138. package/src/lib/server/memory-db.ts +4 -6
  139. package/src/lib/server/memory-tiers.ts +40 -0
  140. package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
  141. package/src/lib/server/openclaw-agent-resolver.ts +128 -0
  142. package/src/lib/server/openclaw-exec-config.ts +5 -6
  143. package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
  144. package/src/lib/server/openclaw-skills-normalize.ts +136 -0
  145. package/src/lib/server/openclaw-sync.ts +3 -2
  146. package/src/lib/server/orchestrator-lg.ts +20 -9
  147. package/src/lib/server/orchestrator.ts +7 -7
  148. package/src/lib/server/playwright-proxy.mjs +27 -3
  149. package/src/lib/server/plugins.test.ts +207 -0
  150. package/src/lib/server/plugins.ts +927 -66
  151. package/src/lib/server/provider-health.ts +38 -6
  152. package/src/lib/server/queue.ts +13 -28
  153. package/src/lib/server/scheduler.ts +2 -0
  154. package/src/lib/server/session-archive-memory.test.ts +85 -0
  155. package/src/lib/server/session-archive-memory.ts +230 -0
  156. package/src/lib/server/session-mailbox.ts +8 -18
  157. package/src/lib/server/session-reset-policy.test.ts +99 -0
  158. package/src/lib/server/session-reset-policy.ts +311 -0
  159. package/src/lib/server/session-run-manager.ts +33 -82
  160. package/src/lib/server/session-tools/autonomy-tools.test.ts +105 -0
  161. package/src/lib/server/session-tools/calendar.ts +366 -0
  162. package/src/lib/server/session-tools/canvas.ts +1 -1
  163. package/src/lib/server/session-tools/chatroom.ts +4 -2
  164. package/src/lib/server/session-tools/connector.ts +114 -10
  165. package/src/lib/server/session-tools/context.ts +21 -5
  166. package/src/lib/server/session-tools/crawl.ts +447 -0
  167. package/src/lib/server/session-tools/crud.ts +74 -28
  168. package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
  169. package/src/lib/server/session-tools/delegate.ts +497 -24
  170. package/src/lib/server/session-tools/discovery.ts +24 -6
  171. package/src/lib/server/session-tools/document.ts +283 -0
  172. package/src/lib/server/session-tools/edit_file.ts +4 -2
  173. package/src/lib/server/session-tools/email.ts +320 -0
  174. package/src/lib/server/session-tools/extract.ts +137 -0
  175. package/src/lib/server/session-tools/file-normalize.test.ts +93 -0
  176. package/src/lib/server/session-tools/file-send.test.ts +84 -1
  177. package/src/lib/server/session-tools/file.ts +241 -25
  178. package/src/lib/server/session-tools/git.ts +1 -1
  179. package/src/lib/server/session-tools/http.ts +1 -1
  180. package/src/lib/server/session-tools/human-loop.ts +227 -0
  181. package/src/lib/server/session-tools/image-gen.ts +380 -0
  182. package/src/lib/server/session-tools/index.ts +130 -50
  183. package/src/lib/server/session-tools/mailbox.ts +276 -0
  184. package/src/lib/server/session-tools/memory.ts +172 -3
  185. package/src/lib/server/session-tools/monitor.ts +151 -8
  186. package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
  187. package/src/lib/server/session-tools/openclaw-nodes.ts +1 -1
  188. package/src/lib/server/session-tools/openclaw-workspace.ts +1 -1
  189. package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
  190. package/src/lib/server/session-tools/platform.ts +148 -7
  191. package/src/lib/server/session-tools/plugin-creator.ts +89 -26
  192. package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
  193. package/src/lib/server/session-tools/replicate.ts +301 -0
  194. package/src/lib/server/session-tools/sample-ui.ts +1 -1
  195. package/src/lib/server/session-tools/sandbox.ts +4 -2
  196. package/src/lib/server/session-tools/schedule.ts +24 -12
  197. package/src/lib/server/session-tools/session-info.ts +43 -7
  198. package/src/lib/server/session-tools/session-tools-wiring.test.ts +31 -17
  199. package/src/lib/server/session-tools/shell.ts +5 -2
  200. package/src/lib/server/session-tools/subagent.ts +194 -28
  201. package/src/lib/server/session-tools/table.ts +587 -0
  202. package/src/lib/server/session-tools/wallet.ts +42 -12
  203. package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
  204. package/src/lib/server/session-tools/web.ts +926 -91
  205. package/src/lib/server/storage.ts +255 -16
  206. package/src/lib/server/stream-agent-chat.ts +116 -268
  207. package/src/lib/server/structured-extract.test.ts +72 -0
  208. package/src/lib/server/structured-extract.ts +373 -0
  209. package/src/lib/server/task-mention.test.ts +16 -2
  210. package/src/lib/server/task-mention.ts +61 -10
  211. package/src/lib/server/tool-aliases.ts +66 -18
  212. package/src/lib/server/tool-capability-policy.test.ts +9 -9
  213. package/src/lib/server/tool-capability-policy.ts +38 -27
  214. package/src/lib/server/tool-retry.ts +2 -0
  215. package/src/lib/server/watch-jobs.test.ts +173 -0
  216. package/src/lib/server/watch-jobs.ts +532 -0
  217. package/src/lib/server/ws-hub.ts +5 -3
  218. package/src/lib/tool-definitions.ts +4 -0
  219. package/src/lib/validation/schemas.test.ts +26 -0
  220. package/src/lib/validation/schemas.ts +10 -1
  221. package/src/lib/ws-client.ts +14 -12
  222. package/src/proxy.ts +5 -5
  223. package/src/stores/use-app-store.ts +5 -11
  224. package/src/stores/use-chat-store.ts +38 -9
  225. package/src/types/index.ts +352 -47
  226. package/src/app/api/sessions/[id]/main-loop/route.ts +0 -94
  227. package/src/components/sessions/new-session-sheet.tsx +0 -253
  228. package/src/lib/server/main-session.ts +0 -24
  229. package/src/lib/server/session-run-manager.test.ts +0 -23
  230. /package/src/app/api/{sessions → chats}/[id]/clear/route.ts +0 -0
  231. /package/src/app/api/{sessions → chats}/[id]/deploy/route.ts +0 -0
  232. /package/src/app/api/{sessions → chats}/[id]/devserver/route.ts +0 -0
  233. /package/src/app/api/{sessions → chats}/[id]/edit-resend/route.ts +0 -0
  234. /package/src/app/api/{sessions → chats}/[id]/fork/route.ts +0 -0
  235. /package/src/app/api/{sessions → chats}/[id]/mailbox/route.ts +0 -0
  236. /package/src/app/api/{sessions → chats}/[id]/retry/route.ts +0 -0
  237. /package/src/app/api/{sessions → chats}/heartbeat/route.ts +0 -0
@@ -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'
@@ -71,6 +72,46 @@ const RAIL_EXPANDED_KEY = 'sc_rail_expanded'
71
72
  const STAR_NOTIFICATION_KEY = 'sc_star_notification_v1'
72
73
  const GITHUB_REPO_URL = 'https://github.com/swarmclawai/swarmclaw'
73
74
 
75
+ const VIEW_LABELS: Record<AppView, string> = {
76
+ home: 'Home',
77
+ agents: 'Agents',
78
+ chatrooms: 'Chatrooms',
79
+ schedules: 'Schedules',
80
+ memory: 'Memory',
81
+ tasks: 'Tasks',
82
+ approvals: 'Approvals',
83
+ secrets: 'Secrets',
84
+ providers: 'Providers',
85
+ skills: 'Skills',
86
+ connectors: 'Connectors',
87
+ webhooks: 'Webhooks',
88
+ mcp_servers: 'MCP Servers',
89
+ knowledge: 'Knowledge',
90
+ logs: 'Logs',
91
+ plugins: 'Plugins',
92
+ usage: 'Usage',
93
+ wallets: 'Wallets',
94
+ runs: 'Runs',
95
+ settings: 'Settings',
96
+ projects: 'Projects',
97
+ activity: 'Activity',
98
+ }
99
+
100
+ const CREATE_LABELS: Partial<Record<AppView, string>> = {
101
+ agents: 'Agent',
102
+ schedules: 'Schedule',
103
+ tasks: 'Task',
104
+ secrets: 'Secret',
105
+ providers: 'Provider',
106
+ skills: 'Skill',
107
+ connectors: 'Connector',
108
+ webhooks: 'Webhook',
109
+ mcp_servers: 'MCP Server',
110
+ knowledge: 'Knowledge Entry',
111
+ plugins: 'Plugin',
112
+ projects: 'Project',
113
+ }
114
+
74
115
  export function AppLayout() {
75
116
  const currentUser = useAppStore((s) => s.currentUser)
76
117
  const sessions = useAppStore((s) => s.sessions)
@@ -92,6 +133,8 @@ export function AppLayout() {
92
133
  const setPluginSheetOpen = useAppStore((s) => s.setPluginSheetOpen)
93
134
  const setProjectSheetOpen = useAppStore((s) => s.setProjectSheetOpen)
94
135
  const tasks = useAppStore((s) => s.tasks)
136
+ const plugins = useAppStore((s) => s.plugins)
137
+ const loadPlugins = useAppStore((s) => s.loadPlugins)
95
138
  const approvals = useAppStore((s) => s.approvals)
96
139
  const loadApprovals = useAppStore((s) => s.loadApprovals)
97
140
  const execApprovals = useApprovalStore((s) => s.approvals)
@@ -131,13 +174,15 @@ export function AppLayout() {
131
174
 
132
175
  const handleShortcutKey = useCallback((e: KeyboardEvent) => {
133
176
  const mod = e.metaKey || e.ctrlKey
134
- // Cmd+N / Ctrl+N — new chat
177
+ // Cmd+N / Ctrl+N — jump to the default agent shortcut
135
178
  if (mod && !e.shiftKey && e.key.toLowerCase() === 'n') {
136
179
  e.preventDefault()
137
180
  const state = useAppStore.getState()
138
- const allAgents = Object.values(state.agents).filter((a) => !a.trashedAt)
139
- const target = allAgents.find((a) => a.id === 'default') || allAgents[0]
140
- if (target) void state.setCurrentAgent(target.id)
181
+ const defaultAgentId = state.appSettings.defaultAgentId && state.agents[state.appSettings.defaultAgentId]
182
+ ? state.appSettings.defaultAgentId
183
+ : Object.values(state.agents)[0]?.id || null
184
+ if (defaultAgentId) void state.setCurrentAgent(defaultAgentId)
185
+ else state.setActiveView('agents')
141
186
  return
142
187
  }
143
188
  // Cmd+Shift+T / Ctrl+Shift+T — jump to tasks
@@ -178,11 +223,27 @@ export function AppLayout() {
178
223
 
179
224
  const [pluginSidebarItems, setPluginSidebarItems] = useState<Array<{ id: string; label: string; href: string }>>([])
180
225
 
181
- useEffect(() => {
226
+ const refreshPluginState = useCallback(() => {
182
227
  api<Array<{ id: string; label: string; href: string }>>('GET', '/plugins/ui?type=sidebar').then(items => {
183
228
  if (Array.isArray(items)) setPluginSidebarItems(items)
184
229
  }).catch(() => {})
185
- }, [])
230
+ void loadPlugins()
231
+ }, [loadPlugins])
232
+
233
+ useEffect(() => { refreshPluginState() }, [refreshPluginState])
234
+
235
+ useWs('plugins', refreshPluginState)
236
+
237
+ const isViewEnabled = useCallback((view: AppView) => {
238
+ if (view === 'chatrooms') return plugins['chatroom']?.enabled !== false
239
+ if (view === 'schedules') return plugins['schedule']?.enabled !== false
240
+ if (view === 'memory') return plugins['memory']?.enabled !== false
241
+ if (view === 'connectors') return plugins['connectors']?.enabled !== false
242
+ if (view === 'webhooks') return plugins['http']?.enabled !== false
243
+ if (view === 'wallets') return plugins['wallet']?.enabled !== false
244
+ if (view === 'logs') return plugins['monitor']?.enabled !== false
245
+ return true
246
+ }, [plugins])
186
247
 
187
248
  const [railExpanded, setRailExpanded] = useState(() => {
188
249
  const stored = safeStorageGet(RAIL_EXPANDED_KEY)
@@ -230,10 +291,11 @@ export function AppLayout() {
230
291
  const agents = useAppStore((s) => s.agents)
231
292
  const currentAgentId = useAppStore((s) => s.currentAgentId)
232
293
  const setCurrentAgent = useAppStore((s) => s.setCurrentAgent)
233
- const defaultAgentId = appSettings.defaultAgentId && agents[appSettings.defaultAgentId]
234
- ? appSettings.defaultAgentId
235
- : Object.values(agents)[0]?.id || null
236
- const isMainChat = activeView === 'agents' && currentAgentId === defaultAgentId
294
+ const defaultAgent = appSettings.defaultAgentId && agents[appSettings.defaultAgentId]
295
+ ? agents[appSettings.defaultAgentId]
296
+ : Object.values(agents)[0] || null
297
+ const defaultAgentId = defaultAgent?.id || null
298
+ const isDefaultChat = activeView === 'agents' && currentAgentId === defaultAgentId
237
299
 
238
300
  const swipeHandlers = useSwipe({
239
301
  onSwipe: (dir) => {
@@ -248,9 +310,11 @@ export function AppLayout() {
248
310
  const hasCanvas = !!(currentSession?.canvasContent && canvasDismissedFor !== currentSessionId)
249
311
  const canvasAgentName = currentSession?.agentId && agents[currentSession.agentId] ? agents[currentSession.agentId].name : undefined
250
312
 
251
- const goToMainChat = async () => {
313
+ const goToDefaultChat = async () => {
252
314
  if (defaultAgentId) {
253
315
  await setCurrentAgent(defaultAgentId)
316
+ } else {
317
+ setActiveView('agents')
254
318
  }
255
319
  setActiveView('agents')
256
320
  setSidebarOpen(false)
@@ -310,32 +374,60 @@ export function AppLayout() {
310
374
  </div>
311
375
  )}
312
376
 
313
- {/* Main Chat shortcut */}
377
+ {/* Default agent shortcut */}
314
378
  {railExpanded ? (
315
- <div className="px-3 mb-2">
379
+ <div className="px-3 mb-2.5">
316
380
  <button
317
- onClick={goToMainChat}
318
- className={`w-full flex items-center gap-2.5 px-3 py-2.5 rounded-[10px] text-[13px] font-600 cursor-pointer transition-all
319
- ${isMainChat
381
+ onClick={goToDefaultChat}
382
+ 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
383
+ ${isDefaultChat
320
384
  ? 'bg-accent-bright/15 border border-[#6366F1]/25 text-accent-bright'
321
385
  : 'bg-accent-bright/10 border border-[#6366F1]/20 text-accent-bright hover:bg-accent-bright/15'}`}
322
386
  style={{ fontFamily: 'inherit' }}
323
387
  >
324
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
325
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
326
- </svg>
327
- Main Chat
388
+ {defaultAgent ? (
389
+ <AgentAvatar
390
+ seed={defaultAgent.avatarSeed || null}
391
+ avatarUrl={defaultAgent.avatarUrl}
392
+ name={defaultAgent.name}
393
+ size={28}
394
+ />
395
+ ) : (
396
+ <div className="w-7 h-7 rounded-full bg-accent-bright/15 flex items-center justify-center shrink-0">
397
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
398
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
399
+ </svg>
400
+ </div>
401
+ )}
402
+ <div className="min-w-0">
403
+ <div className="truncate">{defaultAgent?.name || 'Choose Agent'}</div>
404
+ <div className="text-[10px] font-500 text-accent-bright/75 mt-0.5">
405
+ {defaultAgent ? 'Default shortcut' : 'Pick an agent to open its thread'}
406
+ </div>
407
+ </div>
328
408
  </button>
329
409
  </div>
330
410
  ) : (
331
- <RailTooltip label="Main Chat" description="Your persistent assistant chat">
411
+ <RailTooltip
412
+ label={defaultAgent?.name || 'Choose Agent'}
413
+ description={defaultAgent ? 'Open your default agent shortcut chat' : 'Choose an agent thread'}
414
+ >
332
415
  <button
333
- onClick={goToMainChat}
334
- className={`rail-btn self-center mb-2 ${isMainChat ? 'active' : ''}`}
416
+ onClick={goToDefaultChat}
417
+ className={`rail-btn self-center mb-2 ${isDefaultChat ? 'active' : ''}`}
335
418
  >
336
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
337
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
338
- </svg>
419
+ {defaultAgent ? (
420
+ <AgentAvatar
421
+ seed={defaultAgent.avatarSeed || null}
422
+ avatarUrl={defaultAgent.avatarUrl}
423
+ name={defaultAgent.name}
424
+ size={20}
425
+ />
426
+ ) : (
427
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
428
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
429
+ </svg>
430
+ )}
339
431
  </button>
340
432
  </RailTooltip>
341
433
  )}
@@ -373,114 +465,159 @@ export function AppLayout() {
373
465
 
374
466
  <div className="flex-1 min-h-0 flex flex-col overflow-y-auto overscroll-contain touch-pan-y">
375
467
  {/* Nav items */}
376
- <div className={`flex flex-col gap-0.5 ${railExpanded ? 'px-3' : 'items-center'}`}>
377
- <NavItem view="home" label="Home" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('home')}>
378
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
379
- <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" />
380
- </svg>
381
- </NavItem>
382
- <NavItem view="agents" label="Agents" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('agents')}>
383
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
384
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
385
- </svg>
386
- </NavItem>
387
- <NavItem view="chatrooms" label="Chatrooms" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('chatrooms')}>
388
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
389
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
390
- <path d="M8 10h8" /><path d="M8 14h4" />
391
- </svg>
392
- </NavItem>
393
- <NavItem view="projects" label="Projects" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('projects')}>
394
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
395
- <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" />
396
- </svg>
397
- </NavItem>
398
- <NavItem view="schedules" label="Schedules" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('schedules')}>
399
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
400
- <circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
401
- </svg>
402
- </NavItem>
403
- <NavItem view="memory" label="Memory" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('memory')}>
404
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
405
- <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" />
406
- </svg>
407
- </NavItem>
408
- <NavItem view="tasks" label="Tasks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('tasks')} badge={pendingApprovalCount}>
409
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
410
- <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" />
411
- </svg>
412
- </NavItem>
413
- <NavItem view="approvals" label="Approvals" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('approvals')} badge={pendingApprovalCount}>
414
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
415
- <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
416
- <path d="m9 12 2 2 4-4"/>
417
- </svg>
418
- </NavItem>
419
- <NavItem view="secrets" label="Secrets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('secrets')}>
420
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
421
- <rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
422
- </svg>
423
- </NavItem>
424
- <NavItem view="providers" label="Providers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('providers')}>
425
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
426
- <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" />
427
- </svg>
428
- </NavItem>
429
- <NavItem view="skills" label="Skills" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('skills')}>
430
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
431
- <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" />
432
- </svg>
433
- </NavItem>
434
- <NavItem view="connectors" label="Connectors" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('connectors')}>
435
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
436
- <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" />
437
- </svg>
438
- </NavItem>
439
- <NavItem view="webhooks" label="Webhooks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('webhooks')}>
440
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
441
- <path d="M22 12h-4l-3 7L9 5l-3 7H2" />
442
- </svg>
443
- </NavItem>
444
- <NavItem view="mcp_servers" label="MCP" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('mcp_servers')}>
445
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
446
- <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" />
447
- </svg>
448
- </NavItem>
449
- <NavItem view="knowledge" label="Knowledge" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('knowledge')}>
450
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
451
- <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" />
452
- </svg>
453
- </NavItem>
454
- <NavItem view="plugins" label="Plugins" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('plugins')}>
455
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
456
- <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" />
457
- </svg>
458
- </NavItem>
459
- <NavItem view="usage" label="Usage" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('usage')}>
460
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
461
- <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" />
462
- </svg>
463
- </NavItem>
464
- <NavItem view="wallets" label="Wallets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('wallets')}>
465
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
466
- <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" />
467
- </svg>
468
- </NavItem>
469
- <NavItem view="runs" label="Runs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('runs')}>
470
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
471
- <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
472
- </svg>
473
- </NavItem>
474
- <NavItem view="activity" label="Activity" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('activity')}>
475
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
476
- <path d="M12 8v4l3 3" /><circle cx="12" cy="12" r="10" />
477
- </svg>
478
- </NavItem>
479
- <NavItem view="logs" label="Logs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('logs')}>
480
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
481
- <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" />
482
- </svg>
483
- </NavItem>
468
+ <div className={`flex flex-col gap-3 ${railExpanded ? 'px-3' : 'items-center'}`}>
469
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
470
+ {railExpanded ? (
471
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Workspace</div>
472
+ ) : (
473
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
474
+ )}
475
+ <NavItem view="home" label="Home" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('home')}>
476
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
477
+ <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" />
478
+ </svg>
479
+ </NavItem>
480
+ <NavItem view="agents" label="Agents" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('agents')}>
481
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
482
+ <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
483
+ </svg>
484
+ </NavItem>
485
+ {isViewEnabled('chatrooms') && (
486
+ <NavItem view="chatrooms" label="Chatrooms" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('chatrooms')}>
487
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
488
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
489
+ <path d="M8 10h8" /><path d="M8 14h4" />
490
+ </svg>
491
+ </NavItem>
492
+ )}
493
+ <NavItem view="projects" label="Projects" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('projects')}>
494
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
495
+ <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" />
496
+ </svg>
497
+ </NavItem>
498
+ </div>
499
+
500
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
501
+ {railExpanded ? (
502
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Execution</div>
503
+ ) : (
504
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
505
+ )}
506
+ <NavItem view="tasks" label="Tasks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('tasks')} badge={pendingApprovalCount}>
507
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
508
+ <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" />
509
+ </svg>
510
+ </NavItem>
511
+ <NavItem view="approvals" label="Approvals" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('approvals')} badge={pendingApprovalCount}>
512
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
513
+ <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
514
+ <path d="m9 12 2 2 4-4"/>
515
+ </svg>
516
+ </NavItem>
517
+ {isViewEnabled('schedules') && (
518
+ <NavItem view="schedules" label="Schedules" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('schedules')}>
519
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
520
+ <circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
521
+ </svg>
522
+ </NavItem>
523
+ )}
524
+ {isViewEnabled('memory') && (
525
+ <NavItem view="memory" label="Memory" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('memory')}>
526
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
527
+ <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" />
528
+ </svg>
529
+ </NavItem>
530
+ )}
531
+ <NavItem view="runs" label="Runs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('runs')}>
532
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
533
+ <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
534
+ </svg>
535
+ </NavItem>
536
+ </div>
537
+
538
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
539
+ {railExpanded ? (
540
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Knowledge</div>
541
+ ) : (
542
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
543
+ )}
544
+ <NavItem view="knowledge" label="Knowledge" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('knowledge')}>
545
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
546
+ <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" />
547
+ </svg>
548
+ </NavItem>
549
+ <NavItem view="skills" label="Skills" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('skills')}>
550
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
551
+ <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" />
552
+ </svg>
553
+ </NavItem>
554
+ {isViewEnabled('connectors') && (
555
+ <NavItem view="connectors" label="Connectors" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('connectors')}>
556
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
557
+ <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" />
558
+ </svg>
559
+ </NavItem>
560
+ )}
561
+ {isViewEnabled('webhooks') && (
562
+ <NavItem view="webhooks" label="Webhooks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('webhooks')}>
563
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
564
+ <path d="M22 12h-4l-3 7L9 5l-3 7H2" />
565
+ </svg>
566
+ </NavItem>
567
+ )}
568
+ <NavItem view="mcp_servers" label="MCP Servers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('mcp_servers')}>
569
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
570
+ <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" />
571
+ </svg>
572
+ </NavItem>
573
+ <NavItem view="plugins" label="Plugins" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('plugins')}>
574
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
575
+ <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" />
576
+ </svg>
577
+ </NavItem>
578
+ </div>
579
+
580
+ <div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
581
+ {railExpanded ? (
582
+ <div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">System</div>
583
+ ) : (
584
+ <div className="my-1 h-px w-6 bg-white/[0.06]" />
585
+ )}
586
+ <NavItem view="secrets" label="Secrets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('secrets')}>
587
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
588
+ <rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
589
+ </svg>
590
+ </NavItem>
591
+ <NavItem view="providers" label="Providers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('providers')}>
592
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
593
+ <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" />
594
+ </svg>
595
+ </NavItem>
596
+ <NavItem view="usage" label="Usage" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('usage')}>
597
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
598
+ <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" />
599
+ </svg>
600
+ </NavItem>
601
+ <NavItem view="activity" label="Activity" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('activity')}>
602
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
603
+ <path d="M12 8v4l3 3" /><circle cx="12" cy="12" r="10" />
604
+ </svg>
605
+ </NavItem>
606
+ {isViewEnabled('wallets') && (
607
+ <NavItem view="wallets" label="Wallets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('wallets')}>
608
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
609
+ <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" />
610
+ </svg>
611
+ </NavItem>
612
+ )}
613
+ {isViewEnabled('logs') && (
614
+ <NavItem view="logs" label="Logs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('logs')}>
615
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
616
+ <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" />
617
+ </svg>
618
+ </NavItem>
619
+ )}
620
+ </div>
484
621
  </div>
485
622
 
486
623
  <div className="flex-1" />
@@ -595,7 +732,7 @@ export function AppLayout() {
595
732
  style={{ animation: 'panel-in 0.3s var(--ease-spring)' }}
596
733
  >
597
734
  <div className="flex items-center px-5 pt-5 pb-3 shrink-0">
598
- <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] capitalize flex-1">{activeView}</h2>
735
+ <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] flex-1">{VIEW_LABELS[activeView]}</h2>
599
736
  {activeView === 'logs' || activeView === 'usage' || activeView === 'runs' ? null : activeView === 'memory' ? (
600
737
  <button
601
738
  onClick={() => useAppStore.getState().setMemorySheetOpen(true)}
@@ -617,7 +754,7 @@ export function AppLayout() {
617
754
  <line x1="12" y1="5" x2="12" y2="19" />
618
755
  <line x1="5" y1="12" x2="19" y2="12" />
619
756
  </svg>
620
- {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'}
757
+ {CREATE_LABELS[activeView] || 'New'}
621
758
  </button>
622
759
  )}
623
760
  </div>
@@ -685,32 +822,89 @@ export function AppLayout() {
685
822
  <Avatar user={currentUser!} size="sm" avatarSeed={appSettings.userAvatarSeed} />
686
823
  </button>
687
824
  </div>
688
- {/* View selector tabs */}
689
- <div className="flex px-4 py-2 gap-1 shrink-0 flex-wrap">
690
- {(['agents', 'chatrooms', 'schedules', 'memory', 'tasks', 'secrets', 'providers', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'knowledge', 'plugins', 'usage', 'runs', 'logs'] as AppView[]).map((v) => (
691
- <button
692
- key={v}
693
- onClick={() => setActiveView(v)}
694
- className={`py-2 px-2.5 rounded-[10px] text-[11px] font-600 capitalize cursor-pointer transition-all
695
- ${activeView === v
696
- ? 'bg-accent-soft text-accent-bright'
697
- : 'bg-transparent text-text-3 hover:text-text-2'}`}
698
- style={{ fontFamily: 'inherit' }}
699
- >
700
- {v}
701
- </button>
702
- ))}
703
- {/* Dynamic Plugin Items */}
704
- {pluginSidebarItems.map((item) => (
825
+ {defaultAgent && (
826
+ <div className="px-4 pt-1 pb-3 shrink-0">
705
827
  <button
706
- key={item.id}
707
- onClick={() => window.open(item.href, '_blank')}
708
- 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"
828
+ onClick={goToDefaultChat}
829
+ className={`w-full flex items-center gap-3 rounded-[14px] border px-4 py-3 text-left transition-all cursor-pointer ${
830
+ isDefaultChat
831
+ ? 'bg-accent-soft border-accent-bright/25 text-accent-bright'
832
+ : 'bg-accent-soft/50 border-accent-bright/15 text-accent-bright hover:bg-accent-soft/65'
833
+ }`}
709
834
  style={{ fontFamily: 'inherit' }}
710
835
  >
711
- {item.label}
836
+ <AgentAvatar
837
+ seed={defaultAgent.avatarSeed || null}
838
+ avatarUrl={defaultAgent.avatarUrl}
839
+ name={defaultAgent.name}
840
+ size={32}
841
+ />
842
+ <div className="min-w-0">
843
+ <div className="text-[13px] font-700 truncate">{defaultAgent.name}</div>
844
+ <div className="text-[11px] text-accent-bright/70">Default shortcut</div>
845
+ </div>
712
846
  </button>
713
- ))}
847
+ </div>
848
+ )}
849
+ <div className="px-4 pb-3 shrink-0 max-h-[260px] overflow-y-auto">
850
+ <div className="space-y-4">
851
+ {([
852
+ { label: 'Workspace', views: ['agents', 'chatrooms', 'projects'] as AppView[] },
853
+ { label: 'Execution', views: ['tasks', 'approvals', 'schedules', 'memory', 'runs'] as AppView[] },
854
+ { label: 'Knowledge', views: ['knowledge', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'plugins'] as AppView[] },
855
+ { label: 'System', views: ['secrets', 'providers', 'usage', 'logs'] as AppView[] },
856
+ ]).map((section) => {
857
+ const visibleViews = section.views.filter((view) => isViewEnabled(view))
858
+ if (!visibleViews.length) return null
859
+ return (
860
+ <div key={section.label}>
861
+ <div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
862
+ {section.label}
863
+ </div>
864
+ <div className="grid grid-cols-2 gap-2">
865
+ {visibleViews.map((view) => (
866
+ <button
867
+ key={view}
868
+ onClick={() => {
869
+ setActiveView(view)
870
+ if (FULL_WIDTH_VIEWS.has(view)) setSidebarOpen(false)
871
+ }}
872
+ className={`rounded-[12px] border px-3 py-2.5 text-left transition-all cursor-pointer ${
873
+ activeView === view
874
+ ? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
875
+ : 'bg-transparent border-white/[0.06] text-text-3 hover:text-text hover:bg-white/[0.04]'
876
+ }`}
877
+ style={{ fontFamily: 'inherit' }}
878
+ >
879
+ <div className="text-[12px] font-600">{VIEW_LABELS[view]}</div>
880
+ <div className="text-[10px] text-current/60 mt-1">{VIEW_DESCRIPTIONS[view]}</div>
881
+ </button>
882
+ ))}
883
+ </div>
884
+ </div>
885
+ )
886
+ })}
887
+ {pluginSidebarItems.length > 0 && (
888
+ <div>
889
+ <div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
890
+ Extensions
891
+ </div>
892
+ <div className="grid grid-cols-2 gap-2">
893
+ {pluginSidebarItems.map((item) => (
894
+ <button
895
+ key={item.id}
896
+ onClick={() => window.open(item.href, '_blank')}
897
+ 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"
898
+ style={{ fontFamily: 'inherit' }}
899
+ >
900
+ <div className="text-[12px] font-600">{item.label}</div>
901
+ <div className="text-[10px] text-emerald-300/60 mt-1">Open plugin view</div>
902
+ </button>
903
+ ))}
904
+ </div>
905
+ </div>
906
+ )}
907
+ </div>
714
908
  </div>
715
909
  {activeView !== 'logs' && activeView !== 'usage' && activeView !== 'runs' && activeView !== 'settings' && (
716
910
  <div className="px-4 py-2.5 shrink-0">
@@ -724,7 +918,7 @@ export function AppLayout() {
724
918
  shadow-[0_2px_12px_rgba(99,102,241,0.15)]"
725
919
  style={{ fontFamily: 'inherit' }}
726
920
  >
727
- + 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'}
921
+ + New {CREATE_LABELS[activeView] || 'Entry'}
728
922
  </button>
729
923
  </div>
730
924
  )}
@@ -790,11 +984,27 @@ export function AppLayout() {
790
984
  <div className="flex-1 flex items-center justify-center px-8">
791
985
  <div className="text-center max-w-[420px]">
792
986
  <h2 className="font-display text-[24px] font-700 text-text mb-2 tracking-[-0.02em]">
793
- Select an Agent
987
+ Open a Chat
794
988
  </h2>
795
989
  <p className="text-[14px] text-text-3">
796
- Choose an agent from the sidebar to start chatting.
990
+ Choose a chat from the sidebar, or jump straight into your default agent shortcut.
797
991
  </p>
992
+ <div className="mt-5 flex items-center justify-center gap-3">
993
+ <button
994
+ onClick={defaultAgent ? goToDefaultChat : () => setAgentSheetOpen(true)}
995
+ 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"
996
+ style={{ fontFamily: 'inherit' }}
997
+ >
998
+ {defaultAgent ? `Open ${defaultAgent.name}` : 'Create Agent'}
999
+ </button>
1000
+ <button
1001
+ onClick={() => setAgentSheetOpen(true)}
1002
+ 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"
1003
+ style={{ fontFamily: 'inherit' }}
1004
+ >
1005
+ Create Agent
1006
+ </button>
1007
+ </div>
798
1008
  </div>
799
1009
  </div>
800
1010
  )}
@@ -844,7 +1054,7 @@ export function AppLayout() {
844
1054
  <div className="flex-1 flex flex-col h-full">
845
1055
  <div className="flex items-center px-6 pt-5 pb-3 shrink-0">
846
1056
  <h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] capitalize flex-1">
847
- {activeView === 'mcp_servers' ? 'MCP Servers' : activeView.replace('_', ' ')}
1057
+ {VIEW_LABELS[activeView]}
848
1058
  </h2>
849
1059
  {activeView !== 'runs' && activeView !== 'logs' && (
850
1060
  <button
@@ -855,7 +1065,7 @@ export function AppLayout() {
855
1065
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
856
1066
  <line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
857
1067
  </svg>
858
- {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'}
1068
+ {CREATE_LABELS[activeView] || 'New'}
859
1069
  </button>
860
1070
  )}
861
1071
  </div>
@@ -960,9 +1170,9 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
960
1170
  chatrooms: 'Multi-agent collaborative chatrooms',
961
1171
  schedules: 'Automated task schedules',
962
1172
  memory: 'Long-term agent memory store',
963
- tasks: 'Task board for orchestrator jobs',
1173
+ tasks: 'Task board for agent work and queued runs',
964
1174
  approvals: 'Pending tool execution approvals',
965
- secrets: 'API keys & credentials for orchestrators',
1175
+ secrets: 'API keys, tokens, and encrypted credentials',
966
1176
  providers: 'LLM providers & custom endpoints',
967
1177
  skills: 'Reusable instruction sets for agents',
968
1178
  connectors: 'Chat platform bridges (Discord, Slack, etc.)',
@@ -974,7 +1184,7 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
974
1184
  usage: 'Usage metrics, cost tracking & agent performance',
975
1185
  wallets: 'Agent crypto wallets — hold funds, send SOL, manage spending',
976
1186
  runs: 'Live run monitoring & history',
977
- settings: 'Manage providers, API keys & orchestrator engine',
1187
+ settings: 'Manage defaults, providers, secrets, and automation settings',
978
1188
  projects: 'Group agents, tasks & schedules into projects',
979
1189
  activity: 'Audit trail of all entity mutations',
980
1190
  }
@@ -995,26 +1205,26 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
995
1205
  schedules: {
996
1206
  icon: 'clock',
997
1207
  title: 'Schedules',
998
- description: 'Automate recurring tasks by scheduling orchestrators to run on a cron, interval, or one-time basis.',
999
- features: ['Set up cron expressions for precise timing', 'Run orchestrators automatically on intervals', 'Schedule one-time future tasks', 'View execution history and results'],
1208
+ description: 'Automate recurring work with cron, interval, or one-time schedules that launch agent tasks.',
1209
+ features: ['Set up cron expressions for precise timing', 'Run agents automatically on intervals', 'Schedule one-time future tasks', 'View execution history and results'],
1000
1210
  },
1001
1211
  memory: {
1002
1212
  icon: 'database',
1003
1213
  title: 'Memory',
1004
- description: 'Long-term memory store for AI agents. Orchestrators can store and retrieve knowledge across conversations.',
1214
+ description: 'Long-term memory store for AI agents so they can retain useful context across conversations.',
1005
1215
  features: ['Agents store findings and learnings automatically', 'Full-text search across all stored memories', 'Organized by categories and agents', 'Persists across conversations for continuity'],
1006
1216
  },
1007
1217
  tasks: {
1008
1218
  icon: 'clipboard',
1009
1219
  title: 'Task Board',
1010
- description: 'A Trello-style board for managing orchestrator jobs. Create tasks, assign them to orchestrators, and track progress.',
1011
- 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'],
1220
+ description: 'A kanban board for managing agent work. Create tasks, assign them to agents, and track progress.',
1221
+ features: ['Kanban columns: Backlog, Queued, Running, Completed, Failed', 'Assign tasks to specific agents', 'Track retries, results, and logs', 'Review status without leaving the board'],
1012
1222
  },
1013
1223
  secrets: {
1014
1224
  icon: 'lock',
1015
1225
  title: 'Secrets',
1016
- description: 'Manage API keys and credentials that orchestrators can access during task execution.',
1017
- 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'],
1226
+ description: 'Manage API keys and credentials that agents and integrations can access securely.',
1227
+ 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'],
1018
1228
  },
1019
1229
  providers: {
1020
1230
  icon: 'zap',
@@ -1037,8 +1247,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1037
1247
  webhooks: {
1038
1248
  icon: 'webhook',
1039
1249
  title: 'Webhooks',
1040
- description: 'Receive external events over HTTP and trigger orchestrator runs automatically.',
1041
- 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'],
1250
+ description: 'Receive external events over HTTP and route them into agent-driven workflows automatically.',
1251
+ 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'],
1042
1252
  },
1043
1253
  mcp_servers: {
1044
1254
  icon: 'server',
@@ -1049,7 +1259,7 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1049
1259
  knowledge: {
1050
1260
  icon: 'globe',
1051
1261
  title: 'Knowledge Base',
1052
- description: 'A shared knowledge graph accessible by all agents, enabling cross-agent information sharing and orchestration.',
1262
+ description: 'A shared knowledge graph accessible by all agents for cross-workspace information sharing.',
1053
1263
  features: ['Create tagged knowledge entries', 'Agents can store and search knowledge via tools', 'Full-text and vector search', 'Provenance tracking per entry'],
1054
1264
  },
1055
1265
  logs: {
@@ -1079,8 +1289,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
1079
1289
  settings: {
1080
1290
  icon: 'settings',
1081
1291
  title: 'Settings',
1082
- description: 'Manage providers, API keys & orchestrator engine.',
1083
- features: ['Configure LLM providers', 'Manage API credentials', 'Tune orchestrator settings', 'Set up voice & embedding'],
1292
+ description: 'Manage app defaults, providers, encrypted secrets, and automation settings.',
1293
+ features: ['Choose your default agent shortcut', 'Configure LLM providers and credentials', 'Tune heartbeat and autonomy settings', 'Set up voice, embeddings, and search'],
1084
1294
  },
1085
1295
  projects: {
1086
1296
  icon: 'folder',
@@ -1262,7 +1472,7 @@ function RailTooltip({ label, description, children }: { label: string; descript
1262
1472
  }
1263
1473
 
1264
1474
  function DesktopEmptyState({ userName }: { userName: string | null }) {
1265
- const setNewSessionOpen = useAppStore((s) => s.setNewSessionOpen)
1475
+ const setAgentSheetOpen = useAppStore((s) => s.setAgentSheetOpen)
1266
1476
 
1267
1477
  return (
1268
1478
  <div className="flex-1 flex flex-col items-center justify-center px-8 pb-20 relative overflow-hidden">
@@ -1293,10 +1503,10 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
1293
1503
  <span className="text-text-2">What would you like to do?</span>
1294
1504
  </h1>
1295
1505
  <p className="text-[15px] text-text-3 mb-12">
1296
- Create a new chat to start chatting
1506
+ Create an agent, then keep working in its persistent thread
1297
1507
  </p>
1298
1508
  <button
1299
- onClick={() => setNewSessionOpen(true)}
1509
+ onClick={() => setAgentSheetOpen(true)}
1300
1510
  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
1301
1511
  cursor-pointer hover:brightness-110 active:scale-[0.97] transition-all duration-200
1302
1512
  shadow-[0_6px_28px_rgba(99,102,241,0.3)]"
@@ -1306,7 +1516,7 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
1306
1516
  <line x1="12" y1="5" x2="12" y2="19" />
1307
1517
  <line x1="5" y1="12" x2="19" y2="12" />
1308
1518
  </svg>
1309
- New Chat
1519
+ New Agent
1310
1520
  </button>
1311
1521
  </div>
1312
1522
  </div>