@swarmclawai/swarmclaw 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -7
- package/bin/swarmclaw.js +76 -16
- package/next.config.ts +11 -1
- package/package.json +4 -2
- package/public/screenshots/agents.png +0 -0
- package/public/screenshots/dashboard.png +0 -0
- package/public/screenshots/providers.png +0 -0
- package/public/screenshots/tasks.png +0 -0
- package/scripts/postinstall.mjs +18 -0
- package/src/app/api/chatrooms/[id]/chat/route.ts +410 -0
- package/src/app/api/chatrooms/[id]/members/route.ts +82 -0
- package/src/app/api/chatrooms/[id]/pins/route.ts +39 -0
- package/src/app/api/chatrooms/[id]/reactions/route.ts +42 -0
- package/src/app/api/chatrooms/[id]/route.ts +84 -0
- package/src/app/api/chatrooms/route.ts +50 -0
- package/src/app/api/credentials/route.ts +2 -3
- package/src/app/api/knowledge/[id]/route.ts +13 -2
- package/src/app/api/knowledge/route.ts +8 -1
- package/src/app/api/memory/route.ts +8 -0
- package/src/app/api/notifications/[id]/route.ts +27 -0
- package/src/app/api/notifications/route.ts +68 -0
- package/src/app/api/orchestrator/run/route.ts +1 -1
- package/src/app/api/plugins/install/route.ts +2 -2
- package/src/app/api/search/route.ts +155 -0
- package/src/app/api/sessions/[id]/chat/route.ts +2 -0
- package/src/app/api/sessions/[id]/edit-resend/route.ts +1 -1
- package/src/app/api/sessions/[id]/fork/route.ts +1 -1
- package/src/app/api/sessions/route.ts +3 -3
- package/src/app/api/settings/route.ts +9 -0
- package/src/app/api/setup/check-provider/route.ts +3 -16
- package/src/app/api/skills/[id]/route.ts +6 -0
- package/src/app/api/skills/route.ts +6 -0
- package/src/app/api/tasks/[id]/route.ts +20 -0
- package/src/app/api/tasks/bulk/route.ts +100 -0
- package/src/app/api/tasks/route.ts +1 -0
- package/src/app/api/usage/route.ts +45 -0
- package/src/app/api/webhooks/[id]/route.ts +15 -1
- package/src/app/globals.css +58 -15
- package/src/app/page.tsx +142 -13
- package/src/cli/index.js +42 -0
- package/src/cli/index.test.js +30 -0
- package/src/cli/spec.js +32 -0
- package/src/components/agents/agent-avatar.tsx +57 -10
- package/src/components/agents/agent-card.tsx +48 -15
- package/src/components/agents/agent-chat-list.tsx +123 -10
- package/src/components/agents/agent-list.tsx +50 -19
- package/src/components/agents/agent-sheet.tsx +56 -63
- package/src/components/auth/access-key-gate.tsx +10 -3
- package/src/components/auth/setup-wizard.tsx +2 -2
- package/src/components/auth/user-picker.tsx +31 -3
- package/src/components/chat/activity-moment.tsx +169 -0
- package/src/components/chat/chat-header.tsx +2 -0
- package/src/components/chat/chat-tool-toggles.tsx +1 -1
- package/src/components/chat/file-path-chip.tsx +125 -0
- package/src/components/chat/markdown-utils.ts +9 -0
- package/src/components/chat/message-bubble.tsx +46 -295
- package/src/components/chat/message-list.tsx +50 -1
- package/src/components/chat/streaming-bubble.tsx +36 -46
- package/src/components/chat/suggestions-bar.tsx +1 -1
- package/src/components/chat/thinking-indicator.tsx +72 -10
- package/src/components/chat/tool-call-bubble.tsx +66 -70
- package/src/components/chat/tool-request-banner.tsx +31 -7
- package/src/components/chat/transfer-agent-picker.tsx +63 -0
- package/src/components/chatrooms/agent-hover-card.tsx +124 -0
- package/src/components/chatrooms/chatroom-input.tsx +320 -0
- package/src/components/chatrooms/chatroom-list.tsx +123 -0
- package/src/components/chatrooms/chatroom-message.tsx +427 -0
- package/src/components/chatrooms/chatroom-sheet.tsx +215 -0
- package/src/components/chatrooms/chatroom-tool-request-banner.tsx +134 -0
- package/src/components/chatrooms/chatroom-typing-bar.tsx +88 -0
- package/src/components/chatrooms/chatroom-view.tsx +344 -0
- package/src/components/chatrooms/reaction-picker.tsx +273 -0
- package/src/components/connectors/connector-sheet.tsx +34 -47
- package/src/components/home/home-view.tsx +501 -0
- package/src/components/input/chat-input.tsx +79 -41
- package/src/components/knowledge/knowledge-list.tsx +31 -1
- package/src/components/knowledge/knowledge-sheet.tsx +83 -2
- package/src/components/layout/app-layout.tsx +209 -83
- package/src/components/layout/mobile-header.tsx +2 -0
- package/src/components/layout/update-banner.tsx +2 -2
- package/src/components/logs/log-list.tsx +2 -2
- package/src/components/mcp-servers/mcp-server-sheet.tsx +1 -1
- package/src/components/memory/memory-agent-list.tsx +143 -0
- package/src/components/memory/memory-browser.tsx +205 -0
- package/src/components/memory/memory-card.tsx +34 -7
- package/src/components/memory/memory-detail.tsx +359 -120
- package/src/components/memory/memory-sheet.tsx +157 -23
- package/src/components/plugins/plugin-list.tsx +1 -1
- package/src/components/plugins/plugin-sheet.tsx +1 -1
- package/src/components/projects/project-detail.tsx +509 -0
- package/src/components/projects/project-list.tsx +195 -59
- package/src/components/providers/provider-list.tsx +2 -2
- package/src/components/providers/provider-sheet.tsx +3 -3
- package/src/components/schedules/schedule-card.tsx +3 -2
- package/src/components/schedules/schedule-list.tsx +1 -1
- package/src/components/schedules/schedule-sheet.tsx +25 -25
- package/src/components/secrets/secret-sheet.tsx +47 -24
- package/src/components/secrets/secrets-list.tsx +18 -8
- package/src/components/sessions/new-session-sheet.tsx +33 -65
- package/src/components/sessions/session-card.tsx +45 -14
- package/src/components/sessions/session-list.tsx +35 -18
- package/src/components/shared/agent-picker-list.tsx +90 -0
- package/src/components/shared/agent-switch-dialog.tsx +156 -0
- package/src/components/shared/attachment-chip.tsx +165 -0
- package/src/components/shared/avatar.tsx +10 -1
- package/src/components/shared/check-icon.tsx +12 -0
- package/src/components/shared/confirm-dialog.tsx +1 -1
- package/src/components/shared/empty-state.tsx +32 -0
- package/src/components/shared/file-preview.tsx +34 -0
- package/src/components/shared/form-styles.ts +2 -0
- package/src/components/shared/keyboard-shortcuts-dialog.tsx +116 -0
- package/src/components/shared/notification-center.tsx +223 -0
- package/src/components/shared/profile-sheet.tsx +115 -0
- package/src/components/shared/reply-quote.tsx +26 -0
- package/src/components/shared/search-dialog.tsx +296 -0
- package/src/components/shared/section-label.tsx +12 -0
- package/src/components/shared/settings/plugin-manager.tsx +1 -1
- package/src/components/shared/settings/section-providers.tsx +1 -1
- package/src/components/shared/settings/section-secrets.tsx +1 -1
- package/src/components/shared/settings/section-theme.tsx +95 -0
- package/src/components/shared/settings/section-user-preferences.tsx +39 -0
- package/src/components/shared/settings/settings-page.tsx +180 -27
- package/src/components/shared/settings/settings-sheet.tsx +9 -73
- package/src/components/shared/sheet-footer.tsx +33 -0
- package/src/components/skills/skill-list.tsx +61 -30
- package/src/components/skills/skill-sheet.tsx +81 -2
- package/src/components/tasks/task-board.tsx +448 -26
- package/src/components/tasks/task-card.tsx +46 -9
- package/src/components/tasks/task-column.tsx +62 -3
- package/src/components/tasks/task-list.tsx +12 -4
- package/src/components/tasks/task-sheet.tsx +89 -72
- package/src/components/ui/hover-card.tsx +52 -0
- package/src/components/usage/metrics-dashboard.tsx +78 -0
- package/src/components/usage/usage-list.tsx +1 -1
- package/src/components/webhooks/webhook-sheet.tsx +1 -1
- package/src/hooks/use-view-router.ts +69 -19
- package/src/instrumentation.ts +15 -1
- package/src/lib/chat.ts +2 -0
- package/src/lib/cron-human.ts +114 -0
- package/src/lib/memory.ts +3 -0
- package/src/lib/server/chat-execution.ts +24 -4
- package/src/lib/server/connectors/manager.ts +11 -0
- package/src/lib/server/context-manager.ts +225 -13
- package/src/lib/server/create-notification.ts +42 -0
- package/src/lib/server/daemon-state.ts +165 -10
- package/src/lib/server/execution-log.ts +1 -0
- package/src/lib/server/heartbeat-service.ts +40 -5
- package/src/lib/server/heartbeat-wake.ts +110 -0
- package/src/lib/server/langgraph-checkpoint.ts +1 -0
- package/src/lib/server/memory-consolidation.ts +92 -0
- package/src/lib/server/memory-db.ts +51 -6
- package/src/lib/server/openclaw-gateway.ts +9 -1
- package/src/lib/server/provider-health.ts +125 -0
- package/src/lib/server/queue.ts +5 -4
- package/src/lib/server/scheduler.ts +8 -0
- package/src/lib/server/session-run-manager.ts +4 -0
- package/src/lib/server/session-tools/chatroom.ts +136 -0
- package/src/lib/server/session-tools/context-mgmt.ts +36 -18
- package/src/lib/server/session-tools/index.ts +2 -0
- package/src/lib/server/session-tools/memory.ts +6 -1
- package/src/lib/server/storage.ts +80 -29
- package/src/lib/server/stream-agent-chat.ts +153 -47
- package/src/lib/server/system-events.ts +49 -0
- package/src/lib/server/ws-hub.ts +11 -0
- package/src/lib/soul-suggestions.ts +109 -0
- package/src/lib/tasks.ts +4 -1
- package/src/lib/view-routes.ts +36 -1
- package/src/lib/ws-client.ts +14 -4
- package/src/proxy.ts +79 -2
- package/src/stores/use-app-store.ts +94 -3
- package/src/stores/use-chat-store.ts +48 -3
- package/src/stores/use-chatroom-store.ts +276 -0
- package/src/types/index.ts +69 -2
|
@@ -4,47 +4,183 @@ import { useState } from 'react'
|
|
|
4
4
|
import { useAppStore } from '@/stores/use-app-store'
|
|
5
5
|
import { createMemory } from '@/lib/memory'
|
|
6
6
|
import { BottomSheet } from '@/components/shared/bottom-sheet'
|
|
7
|
+
import { AgentAvatar } from '@/components/agents/agent-avatar'
|
|
8
|
+
import { SheetFooter } from '@/components/shared/sheet-footer'
|
|
9
|
+
import { inputClass } from '@/components/shared/form-styles'
|
|
10
|
+
|
|
11
|
+
const CATEGORIES = ['note', 'fact', 'preference', 'finding', 'learning', 'general']
|
|
7
12
|
|
|
8
13
|
export function MemorySheet() {
|
|
9
14
|
const open = useAppStore((s) => s.memorySheetOpen)
|
|
10
15
|
const setOpen = useAppStore((s) => s.setMemorySheetOpen)
|
|
11
16
|
const triggerRefresh = useAppStore((s) => s.triggerMemoryRefresh)
|
|
17
|
+
const agents = useAppStore((s) => s.agents)
|
|
18
|
+
const memoryAgentFilter = useAppStore((s) => s.memoryAgentFilter)
|
|
19
|
+
|
|
20
|
+
// Track open transitions to reset form
|
|
21
|
+
const [prevOpen, setPrevOpen] = useState(false)
|
|
22
|
+
const defaultAgentId = memoryAgentFilter && memoryAgentFilter !== '_global' ? memoryAgentFilter : null
|
|
12
23
|
|
|
13
24
|
const [title, setTitle] = useState('')
|
|
14
25
|
const [content, setContent] = useState('')
|
|
26
|
+
const [category, setCategory] = useState('note')
|
|
27
|
+
const [agentId, setAgentId] = useState<string | null>(defaultAgentId)
|
|
28
|
+
const [sharedWith, setSharedWith] = useState<string[]>([])
|
|
29
|
+
const [saving, setSaving] = useState(false)
|
|
15
30
|
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
// Reset form when sheet opens (getDerivedStateFromProps pattern)
|
|
32
|
+
if (open && !prevOpen) {
|
|
33
|
+
setPrevOpen(true)
|
|
34
|
+
setAgentId(defaultAgentId)
|
|
35
|
+
setSharedWith([])
|
|
18
36
|
setTitle('')
|
|
19
37
|
setContent('')
|
|
38
|
+
setCategory('note')
|
|
39
|
+
setSaving(false)
|
|
40
|
+
} else if (!open && prevOpen) {
|
|
41
|
+
setPrevOpen(false)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const onClose = () => {
|
|
45
|
+
setOpen(false)
|
|
20
46
|
}
|
|
21
47
|
|
|
22
48
|
const handleSave = async () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
49
|
+
if (!title.trim()) return
|
|
50
|
+
setSaving(true)
|
|
51
|
+
try {
|
|
52
|
+
await createMemory({
|
|
53
|
+
title: title.trim(),
|
|
54
|
+
category,
|
|
55
|
+
content,
|
|
56
|
+
agentId,
|
|
57
|
+
sessionId: null,
|
|
58
|
+
sharedWith: sharedWith.length ? sharedWith : undefined,
|
|
59
|
+
})
|
|
60
|
+
triggerRefresh()
|
|
61
|
+
onClose()
|
|
62
|
+
} catch {
|
|
63
|
+
/* ignore */
|
|
64
|
+
}
|
|
65
|
+
setSaving(false)
|
|
32
66
|
}
|
|
33
67
|
|
|
34
|
-
const
|
|
68
|
+
const agentList = Object.values(agents).sort((a, b) => a.name.localeCompare(b.name))
|
|
69
|
+
const selectedAgent = agentId ? agents[agentId] : null
|
|
35
70
|
|
|
36
71
|
return (
|
|
37
72
|
<BottomSheet open={open} onClose={onClose}>
|
|
38
|
-
<div className="mb-
|
|
73
|
+
<div className="mb-8">
|
|
39
74
|
<h2 className="font-display text-[28px] font-700 tracking-[-0.03em] mb-2">New Memory</h2>
|
|
40
|
-
<p className="text-[14px] text-text-3">Store a piece of knowledge</p>
|
|
75
|
+
<p className="text-[14px] text-text-3">Store a piece of knowledge for an agent or globally</p>
|
|
41
76
|
</div>
|
|
42
77
|
|
|
43
|
-
|
|
78
|
+
{/* Agent selector */}
|
|
79
|
+
<div className="mb-6">
|
|
80
|
+
<label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">Assign to</label>
|
|
81
|
+
<div className="flex gap-2 flex-wrap">
|
|
82
|
+
<button
|
|
83
|
+
onClick={() => setAgentId(null)}
|
|
84
|
+
className={`flex items-center gap-2 px-3 py-2 rounded-[10px] text-[13px] font-600 cursor-pointer transition-all border
|
|
85
|
+
${!agentId
|
|
86
|
+
? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
|
|
87
|
+
: 'bg-white/[0.02] border-white/[0.06] text-text-3 hover:text-text-2 hover:bg-white/[0.04]'}`}
|
|
88
|
+
style={{ fontFamily: 'inherit' }}
|
|
89
|
+
>
|
|
90
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" className={!agentId ? 'text-accent-bright' : 'text-text-3/60'}>
|
|
91
|
+
<circle cx="12" cy="12" r="10" />
|
|
92
|
+
<line x1="2" y1="12" x2="22" y2="12" />
|
|
93
|
+
<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" />
|
|
94
|
+
</svg>
|
|
95
|
+
Global
|
|
96
|
+
</button>
|
|
97
|
+
{agentList.map((agent) => (
|
|
98
|
+
<button
|
|
99
|
+
key={agent.id}
|
|
100
|
+
onClick={() => setAgentId(agent.id)}
|
|
101
|
+
className={`flex items-center gap-2 px-3 py-2 rounded-[10px] text-[13px] font-600 cursor-pointer transition-all border
|
|
102
|
+
${agentId === agent.id
|
|
103
|
+
? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
|
|
104
|
+
: 'bg-white/[0.02] border-white/[0.06] text-text-3 hover:text-text-2 hover:bg-white/[0.04]'}`}
|
|
105
|
+
style={{ fontFamily: 'inherit' }}
|
|
106
|
+
>
|
|
107
|
+
<AgentAvatar seed={agent.avatarSeed || null} name={agent.name} size={20} />
|
|
108
|
+
<span className="truncate max-w-[120px]">{agent.name}</span>
|
|
109
|
+
</button>
|
|
110
|
+
))}
|
|
111
|
+
</div>
|
|
112
|
+
{selectedAgent && (
|
|
113
|
+
<p className="text-[11px] text-text-3/50 mt-2">
|
|
114
|
+
This memory will be available to <span className="text-text-2">{selectedAgent.name}</span> during conversations
|
|
115
|
+
</p>
|
|
116
|
+
)}
|
|
117
|
+
{!agentId && (
|
|
118
|
+
<p className="text-[11px] text-text-3/50 mt-2">
|
|
119
|
+
Global memories are accessible to all agents
|
|
120
|
+
</p>
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
{/* Share with (only when assigned to an agent) */}
|
|
125
|
+
{agentId && agentList.filter((a) => a.id !== agentId).length > 0 && (
|
|
126
|
+
<div className="mb-6">
|
|
127
|
+
<label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">Share with</label>
|
|
128
|
+
<div className="flex gap-2 flex-wrap">
|
|
129
|
+
{agentList
|
|
130
|
+
.filter((a) => a.id !== agentId)
|
|
131
|
+
.map((agent) => {
|
|
132
|
+
const isShared = sharedWith.includes(agent.id)
|
|
133
|
+
return (
|
|
134
|
+
<button
|
|
135
|
+
key={agent.id}
|
|
136
|
+
onClick={() => setSharedWith(isShared ? sharedWith.filter((id) => id !== agent.id) : [...sharedWith, agent.id])}
|
|
137
|
+
className={`flex items-center gap-2 px-3 py-2 rounded-[10px] text-[13px] font-600 cursor-pointer transition-all border
|
|
138
|
+
${isShared
|
|
139
|
+
? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
|
|
140
|
+
: 'bg-white/[0.02] border-white/[0.06] text-text-3 hover:text-text-2 hover:bg-white/[0.04]'}`}
|
|
141
|
+
style={{ fontFamily: 'inherit' }}
|
|
142
|
+
>
|
|
143
|
+
<AgentAvatar seed={agent.avatarSeed || null} name={agent.name} size={20} />
|
|
144
|
+
<span className="truncate max-w-[120px]">{agent.name}</span>
|
|
145
|
+
</button>
|
|
146
|
+
)
|
|
147
|
+
})}
|
|
148
|
+
</div>
|
|
149
|
+
{sharedWith.length > 0 && (
|
|
150
|
+
<p className="text-[11px] text-text-3/50 mt-2">
|
|
151
|
+
Shared with {sharedWith.length} agent{sharedWith.length === 1 ? '' : 's'} in addition to the owner
|
|
152
|
+
</p>
|
|
153
|
+
)}
|
|
154
|
+
</div>
|
|
155
|
+
)}
|
|
156
|
+
|
|
157
|
+
{/* Title */}
|
|
158
|
+
<div className="mb-6">
|
|
44
159
|
<label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">Title</label>
|
|
45
160
|
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Memory title" className={inputClass} style={{ fontFamily: 'inherit' }} />
|
|
46
161
|
</div>
|
|
47
162
|
|
|
163
|
+
{/* Category */}
|
|
164
|
+
<div className="mb-6">
|
|
165
|
+
<label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">Category</label>
|
|
166
|
+
<div className="flex gap-1.5 flex-wrap">
|
|
167
|
+
{CATEGORIES.map((c) => (
|
|
168
|
+
<button
|
|
169
|
+
key={c}
|
|
170
|
+
onClick={() => setCategory(c)}
|
|
171
|
+
className={`px-3 py-1.5 rounded-[8px] text-[12px] font-600 capitalize cursor-pointer transition-all border-none
|
|
172
|
+
${category === c
|
|
173
|
+
? 'bg-accent-soft text-accent-bright'
|
|
174
|
+
: 'bg-white/[0.03] text-text-3 hover:text-text-2 hover:bg-white/[0.05]'}`}
|
|
175
|
+
style={{ fontFamily: 'inherit' }}
|
|
176
|
+
>
|
|
177
|
+
{c}
|
|
178
|
+
</button>
|
|
179
|
+
))}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
{/* Content */}
|
|
48
184
|
<div className="mb-8">
|
|
49
185
|
<label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">Content</label>
|
|
50
186
|
<textarea
|
|
@@ -57,14 +193,12 @@ export function MemorySheet() {
|
|
|
57
193
|
/>
|
|
58
194
|
</div>
|
|
59
195
|
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</button>
|
|
67
|
-
</div>
|
|
196
|
+
<SheetFooter
|
|
197
|
+
onCancel={onClose}
|
|
198
|
+
onSave={handleSave}
|
|
199
|
+
saveLabel={saving ? 'Saving...' : 'Save'}
|
|
200
|
+
saveDisabled={!title.trim() || saving}
|
|
201
|
+
/>
|
|
68
202
|
</BottomSheet>
|
|
69
203
|
)
|
|
70
204
|
}
|
|
@@ -224,7 +224,7 @@ export function PluginList({ inSidebar }: { inSidebar?: boolean }) {
|
|
|
224
224
|
<div
|
|
225
225
|
onClick={(e) => handleToggle(e, plugin.filename, plugin.enabled)}
|
|
226
226
|
className={`w-9 h-5 rounded-full transition-all relative cursor-pointer shrink-0
|
|
227
|
-
${plugin.enabled ? 'bg-
|
|
227
|
+
${plugin.enabled ? 'bg-accent-bright' : 'bg-white/[0.08]'}`}
|
|
228
228
|
>
|
|
229
229
|
<div className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-all
|
|
230
230
|
${plugin.enabled ? 'left-[18px]' : 'left-0.5'}`} />
|
|
@@ -116,7 +116,7 @@ export function PluginSheet() {
|
|
|
116
116
|
<div
|
|
117
117
|
onClick={() => togglePlugin(editing.filename, !editing.enabled)}
|
|
118
118
|
className={`w-11 h-6 rounded-full transition-all duration-200 relative cursor-pointer shrink-0
|
|
119
|
-
${editing.enabled ? 'bg-
|
|
119
|
+
${editing.enabled ? 'bg-accent-bright' : 'bg-white/[0.08]'}`}
|
|
120
120
|
>
|
|
121
121
|
<div className={`absolute top-0.5 w-5 h-5 rounded-full bg-white transition-all duration-200
|
|
122
122
|
${editing.enabled ? 'left-[22px]' : 'left-0.5'}`} />
|