@desplega.ai/agent-swarm 1.2.1 → 1.9.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/.claude/settings.local.json +20 -1
- package/.env.docker.example +22 -1
- package/.env.example +17 -0
- package/.github/workflows/docker-publish.yml +92 -0
- package/CONTRIBUTING.md +270 -0
- package/DEPLOYMENT.md +391 -0
- package/Dockerfile.worker +29 -1
- package/FAQ.md +19 -0
- package/LICENSE +21 -0
- package/MCP.md +249 -0
- package/README.md +103 -207
- package/assets/agent-swarm-logo-orange.png +0 -0
- package/assets/agent-swarm-logo.png +0 -0
- package/docker-compose.example.yml +137 -0
- package/docker-entrypoint.sh +223 -7
- package/package.json +8 -3
- package/{cc-plugin → plugin}/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +1 -0
- package/plugin/agents/.gitkeep +0 -0
- package/plugin/agents/codebase-analyzer.md +143 -0
- package/plugin/agents/codebase-locator.md +122 -0
- package/plugin/agents/codebase-pattern-finder.md +227 -0
- package/plugin/agents/web-search-researcher.md +109 -0
- package/plugin/commands/create-plan.md +415 -0
- package/plugin/commands/implement-plan.md +89 -0
- package/plugin/commands/research.md +200 -0
- package/plugin/commands/start-leader.md +101 -0
- package/plugin/commands/start-worker.md +56 -0
- package/plugin/commands/swarm-chat.md +78 -0
- package/plugin/commands/todos.md +66 -0
- package/plugin/commands/work-on-task.md +44 -0
- package/plugin/skills/.gitkeep +0 -0
- package/scripts/generate-mcp-docs.ts +415 -0
- package/slack-manifest.json +69 -0
- package/src/be/db.ts +1431 -25
- package/src/cli.tsx +135 -11
- package/src/commands/lead.ts +13 -0
- package/src/commands/runner.ts +255 -0
- package/src/commands/worker.ts +8 -220
- package/src/hooks/hook.ts +102 -14
- package/src/http.ts +361 -5
- package/src/prompts/base-prompt.ts +131 -0
- package/src/server.ts +56 -0
- package/src/slack/app.ts +73 -0
- package/src/slack/commands.ts +88 -0
- package/src/slack/handlers.ts +281 -0
- package/src/slack/index.ts +3 -0
- package/src/slack/responses.ts +175 -0
- package/src/slack/router.ts +170 -0
- package/src/slack/types.ts +20 -0
- package/src/slack/watcher.ts +119 -0
- package/src/tools/create-channel.ts +80 -0
- package/src/tools/get-tasks.ts +54 -21
- package/src/tools/join-swarm.ts +28 -4
- package/src/tools/list-channels.ts +37 -0
- package/src/tools/list-services.ts +110 -0
- package/src/tools/poll-task.ts +46 -3
- package/src/tools/post-message.ts +87 -0
- package/src/tools/read-messages.ts +192 -0
- package/src/tools/register-service.ts +118 -0
- package/src/tools/send-task.ts +80 -7
- package/src/tools/store-progress.ts +9 -3
- package/src/tools/task-action.ts +211 -0
- package/src/tools/unregister-service.ts +110 -0
- package/src/tools/update-profile.ts +105 -0
- package/src/tools/update-service-status.ts +118 -0
- package/src/types.ts +110 -3
- package/src/utils/pretty-print.ts +224 -0
- package/thoughts/shared/plans/.gitkeep +0 -0
- package/thoughts/shared/plans/2025-12-18-inverse-teleport.md +1142 -0
- package/thoughts/shared/plans/2025-12-18-slack-integration.md +1195 -0
- package/thoughts/shared/plans/2025-12-19-agent-log-streaming.md +732 -0
- package/thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md +361 -0
- package/thoughts/shared/plans/2025-12-20-mobile-responsive-ui.md +501 -0
- package/thoughts/shared/plans/2025-12-20-startup-team-swarm.md +560 -0
- package/thoughts/shared/research/.gitkeep +0 -0
- package/thoughts/shared/research/2025-12-18-slack-integration.md +442 -0
- package/thoughts/shared/research/2025-12-19-agent-log-streaming.md +339 -0
- package/thoughts/shared/research/2025-12-19-agent-secrets-cli-research.md +390 -0
- package/thoughts/shared/research/2025-12-21-gemini-cli-integration.md +376 -0
- package/thoughts/shared/research/2025-12-22-setup-experience-improvements.md +264 -0
- package/tsconfig.json +3 -1
- package/ui/bun.lock +692 -0
- package/ui/index.html +22 -0
- package/ui/package.json +32 -0
- package/ui/pnpm-lock.yaml +3034 -0
- package/ui/postcss.config.js +6 -0
- package/ui/public/logo.png +0 -0
- package/ui/src/App.tsx +43 -0
- package/ui/src/components/ActivityFeed.tsx +415 -0
- package/ui/src/components/AgentDetailPanel.tsx +534 -0
- package/ui/src/components/AgentsPanel.tsx +549 -0
- package/ui/src/components/ChatPanel.tsx +1820 -0
- package/ui/src/components/ConfigModal.tsx +232 -0
- package/ui/src/components/Dashboard.tsx +534 -0
- package/ui/src/components/Header.tsx +168 -0
- package/ui/src/components/ServicesPanel.tsx +612 -0
- package/ui/src/components/StatsBar.tsx +288 -0
- package/ui/src/components/StatusBadge.tsx +124 -0
- package/ui/src/components/TaskDetailPanel.tsx +807 -0
- package/ui/src/components/TasksPanel.tsx +575 -0
- package/ui/src/hooks/queries.ts +170 -0
- package/ui/src/index.css +235 -0
- package/ui/src/lib/api.ts +161 -0
- package/ui/src/lib/config.ts +35 -0
- package/ui/src/lib/theme.ts +214 -0
- package/ui/src/lib/utils.ts +48 -0
- package/ui/src/main.tsx +32 -0
- package/ui/src/types/api.ts +164 -0
- package/ui/src/vite-env.d.ts +1 -0
- package/ui/tailwind.config.js +35 -0
- package/ui/tsconfig.json +31 -0
- package/ui/vite.config.ts +22 -0
- package/cc-plugin/README.md +0 -49
- package/cc-plugin/commands/setup-leader.md +0 -73
- package/cc-plugin/commands/start-worker.md +0 -64
- package/docker-compose.worker.yml +0 -35
- package/example-req-meta.json +0 -24
- /package/{cc-plugin → plugin}/hooks/hooks.json +0 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# Mobile Responsive UI Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Make the agent-swarm dashboard fully responsive on mobile devices (320px-480px) and tablets (768px-1024px) while preserving the existing desktop experience.
|
|
6
|
+
|
|
7
|
+
## Current State Analysis
|
|
8
|
+
|
|
9
|
+
- **Framework**: MUI Joy UI with custom CSS
|
|
10
|
+
- **Layout**: Tabbed master-detail pattern assuming wide viewport
|
|
11
|
+
- **Styling**: Custom "beehive" theme with amber/gold colors, glow effects
|
|
12
|
+
- **Issue**: No mobile responsiveness - fixed flex layouts, hardcoded widths, no breakpoints
|
|
13
|
+
|
|
14
|
+
### Key Discoveries:
|
|
15
|
+
- Dashboard uses `display: flex` with fixed `gap: 3` (24px) horizontal layouts
|
|
16
|
+
- Detail panels have fixed widths: AgentDetailPanel 400px, TaskDetailPanel 450px
|
|
17
|
+
- Tables with 5-8 columns unusable on mobile
|
|
18
|
+
- ChatPanel channel list fixed at `width: 220`
|
|
19
|
+
- Padding throughout uses `px: 3` (24px) - too large for mobile
|
|
20
|
+
- No media queries or responsive breakpoints defined
|
|
21
|
+
|
|
22
|
+
## Desired End State
|
|
23
|
+
|
|
24
|
+
1. App fully usable on mobile phones (320px-480px width)
|
|
25
|
+
2. Tablet experience optimized (768px-1024px)
|
|
26
|
+
3. Desktop experience unchanged
|
|
27
|
+
4. Beehive theme aesthetic maintained across all breakpoints
|
|
28
|
+
|
|
29
|
+
### Verification:
|
|
30
|
+
- Open app in Chrome DevTools mobile view (iPhone SE, Pixel 5)
|
|
31
|
+
- All tabs accessible and functional
|
|
32
|
+
- Detail panels usable without horizontal scroll
|
|
33
|
+
- Touch targets minimum 44x44px
|
|
34
|
+
|
|
35
|
+
## What We're NOT Doing
|
|
36
|
+
|
|
37
|
+
- **Changing component structure** - Keep existing component hierarchy
|
|
38
|
+
- **Adding new tabs/pages** - ActivityFeed hidden on mobile, not moved to tab
|
|
39
|
+
- **Breaking desktop layout** - All changes use responsive breakpoints
|
|
40
|
+
- **Redesigning visual theme** - Colors, glows, hexagons stay the same
|
|
41
|
+
|
|
42
|
+
## Implementation Approach
|
|
43
|
+
|
|
44
|
+
Mobile-first responsive design using MUI Joy's `sx` prop with breakpoint objects (e.g., `{ xs: value, md: value, lg: value }`).
|
|
45
|
+
|
|
46
|
+
**Breakpoints** (MUI defaults):
|
|
47
|
+
- `xs`: 0-599px (phones)
|
|
48
|
+
- `sm`: 600-899px (small tablets)
|
|
49
|
+
- `md`: 900-1199px (tablets)
|
|
50
|
+
- `lg`: 1200px+ (desktop - current behavior preserved)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Phase 1: Dashboard Core Layout ✅
|
|
55
|
+
|
|
56
|
+
### Overview
|
|
57
|
+
Update the main Dashboard layout to stack vertically on mobile and handle detail panels as overlays.
|
|
58
|
+
|
|
59
|
+
### Changes Required:
|
|
60
|
+
|
|
61
|
+
#### 1. Dashboard.tsx
|
|
62
|
+
|
|
63
|
+
**Responsive padding** (line ~294):
|
|
64
|
+
```tsx
|
|
65
|
+
sx={{
|
|
66
|
+
px: { xs: 1.5, sm: 2, md: 3 }, // was: px: 3
|
|
67
|
+
pt: { xs: 1.5, md: 2 },
|
|
68
|
+
pb: { xs: 2, md: 3 },
|
|
69
|
+
}}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Scrollable tabs** (line ~307-343):
|
|
73
|
+
```tsx
|
|
74
|
+
<TabList sx={{
|
|
75
|
+
overflowX: { xs: "auto", md: "visible" },
|
|
76
|
+
flexWrap: { xs: "nowrap", md: "wrap" },
|
|
77
|
+
"& .MuiTab-root": {
|
|
78
|
+
px: { xs: 2, md: 3 },
|
|
79
|
+
fontSize: { xs: "0.7rem", md: "0.8rem" },
|
|
80
|
+
},
|
|
81
|
+
}}/>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Master-detail stack on mobile** (line ~358):
|
|
85
|
+
```tsx
|
|
86
|
+
<Box sx={{
|
|
87
|
+
flexDirection: { xs: "column", lg: "row" },
|
|
88
|
+
gap: { xs: 2, md: 3 },
|
|
89
|
+
}}>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Hide master panel when detail selected on mobile**:
|
|
93
|
+
```tsx
|
|
94
|
+
<Box sx={{
|
|
95
|
+
display: {
|
|
96
|
+
xs: selectedAgentId ? "none" : "flex",
|
|
97
|
+
md: "flex"
|
|
98
|
+
},
|
|
99
|
+
}}>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Hide ActivityFeed on mobile**:
|
|
103
|
+
```tsx
|
|
104
|
+
<Box sx={{
|
|
105
|
+
display: { xs: "none", lg: "block" }
|
|
106
|
+
}}>
|
|
107
|
+
<ActivityFeed />
|
|
108
|
+
</Box>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Success Criteria:
|
|
112
|
+
|
|
113
|
+
#### Automated Verification:
|
|
114
|
+
- [x] `bun run tsc` passes with no type errors
|
|
115
|
+
- [x] App renders without console errors in mobile viewport
|
|
116
|
+
|
|
117
|
+
#### Manual Verification:
|
|
118
|
+
- [ ] Tabs scroll horizontally on mobile
|
|
119
|
+
- [ ] Master panel hides when detail selected on mobile
|
|
120
|
+
- [ ] ActivityFeed hidden on screens < 1200px
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Phase 2: Header Component ✅
|
|
125
|
+
|
|
126
|
+
### Overview
|
|
127
|
+
Reduce header padding and title size on mobile.
|
|
128
|
+
|
|
129
|
+
### Changes Required:
|
|
130
|
+
|
|
131
|
+
#### Header.tsx
|
|
132
|
+
|
|
133
|
+
**Responsive padding** (line ~48):
|
|
134
|
+
```tsx
|
|
135
|
+
<Box sx={{
|
|
136
|
+
px: { xs: 1.5, sm: 2, md: 3 },
|
|
137
|
+
py: { xs: 1.5, md: 2 },
|
|
138
|
+
}}>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Responsive title** (line ~62):
|
|
142
|
+
```tsx
|
|
143
|
+
<Typography sx={{
|
|
144
|
+
fontSize: { xs: "1.1rem", sm: "1.25rem", md: "1.5rem" },
|
|
145
|
+
letterSpacing: { xs: "0.1em", md: "0.15em" },
|
|
146
|
+
}}>
|
|
147
|
+
<Box component="span" sx={{ display: { xs: "none", sm: "inline" } }}>
|
|
148
|
+
AGENT SWARM
|
|
149
|
+
</Box>
|
|
150
|
+
<Box component="span" sx={{ display: { xs: "inline", sm: "none" } }}>
|
|
151
|
+
SWARM
|
|
152
|
+
</Box>
|
|
153
|
+
</Typography>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Reduce button gap**:
|
|
157
|
+
```tsx
|
|
158
|
+
<Box sx={{ gap: { xs: 0.75, md: 1.5 } }}>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Success Criteria:
|
|
162
|
+
|
|
163
|
+
#### Manual Verification:
|
|
164
|
+
- [ ] Header fits on 320px viewport without overflow
|
|
165
|
+
- [ ] Title shows "SWARM" on mobile, "AGENT SWARM" on desktop
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Phase 3: Detail Panels - Full Screen Mobile Overlay ✅
|
|
170
|
+
|
|
171
|
+
### Overview
|
|
172
|
+
Convert AgentDetailPanel and TaskDetailPanel to full-screen overlays on mobile.
|
|
173
|
+
|
|
174
|
+
### Changes Required:
|
|
175
|
+
|
|
176
|
+
#### AgentDetailPanel.tsx
|
|
177
|
+
|
|
178
|
+
**Full screen on mobile** (line ~382):
|
|
179
|
+
```tsx
|
|
180
|
+
<Box sx={{
|
|
181
|
+
position: { xs: "fixed", md: "relative" },
|
|
182
|
+
inset: { xs: 0, md: "auto" },
|
|
183
|
+
zIndex: { xs: 1300, md: "auto" },
|
|
184
|
+
width: { xs: "100%", md: expanded ? "100%" : 400 },
|
|
185
|
+
height: { xs: "100%", md: "100%" },
|
|
186
|
+
borderRadius: { xs: 0, md: "12px" },
|
|
187
|
+
}}>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Add mobile back button**:
|
|
191
|
+
```tsx
|
|
192
|
+
<IconButton
|
|
193
|
+
sx={{ display: { xs: "flex", md: "none" } }}
|
|
194
|
+
onClick={onClose}
|
|
195
|
+
>
|
|
196
|
+
<ArrowLeftIcon />
|
|
197
|
+
</IconButton>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Reduce padding**:
|
|
201
|
+
```tsx
|
|
202
|
+
<Box sx={{ p: { xs: 1.5, md: 2 } }}>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### TaskDetailPanel.tsx
|
|
206
|
+
|
|
207
|
+
Apply same patterns as AgentDetailPanel.
|
|
208
|
+
|
|
209
|
+
### Success Criteria:
|
|
210
|
+
|
|
211
|
+
#### Manual Verification:
|
|
212
|
+
- [ ] Detail panels cover full screen on mobile
|
|
213
|
+
- [ ] Back button visible and functional on mobile
|
|
214
|
+
- [ ] Panels close properly when back button pressed
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Phase 4: Agents Panel - Table to Cards ✅
|
|
219
|
+
|
|
220
|
+
### Overview
|
|
221
|
+
Replace table with card-based layout on mobile.
|
|
222
|
+
|
|
223
|
+
### Changes Required:
|
|
224
|
+
|
|
225
|
+
#### AgentsPanel.tsx
|
|
226
|
+
|
|
227
|
+
**Create AgentCard component**:
|
|
228
|
+
```tsx
|
|
229
|
+
function AgentCard({ agent, selected, onClick }) {
|
|
230
|
+
return (
|
|
231
|
+
<Box onClick={onClick} sx={{
|
|
232
|
+
p: 2,
|
|
233
|
+
mb: 1,
|
|
234
|
+
borderRadius: "8px",
|
|
235
|
+
border: "1px solid",
|
|
236
|
+
borderColor: selected ? colors.amber : "neutral.outlinedBorder",
|
|
237
|
+
}}>
|
|
238
|
+
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 1 }}>
|
|
239
|
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
|
240
|
+
<StatusDot status={agent.status} />
|
|
241
|
+
<Typography fontWeight={600}>{agent.name}</Typography>
|
|
242
|
+
{agent.isLead && <Chip size="sm">LEAD</Chip>}
|
|
243
|
+
</Box>
|
|
244
|
+
<StatusBadge status={agent.status} />
|
|
245
|
+
</Box>
|
|
246
|
+
<Typography fontSize="0.75rem" color="text.tertiary">
|
|
247
|
+
{agent.role || "No role"} · {activeTasks}/{agent.tasks.length} tasks
|
|
248
|
+
</Typography>
|
|
249
|
+
</Box>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Responsive filters**:
|
|
255
|
+
```tsx
|
|
256
|
+
<Box sx={{
|
|
257
|
+
flexDirection: { xs: "column", sm: "row" },
|
|
258
|
+
alignItems: { xs: "stretch", sm: "center" },
|
|
259
|
+
}}>
|
|
260
|
+
<Input sx={{ minWidth: { xs: "100%", sm: 140 } }} />
|
|
261
|
+
<Select sx={{ minWidth: { xs: "100%", sm: 100 } }} />
|
|
262
|
+
</Box>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Conditional table/cards**:
|
|
266
|
+
```tsx
|
|
267
|
+
{/* Desktop Table */}
|
|
268
|
+
<Box sx={{ display: { xs: "none", md: "block" } }}>
|
|
269
|
+
<Table>...</Table>
|
|
270
|
+
</Box>
|
|
271
|
+
|
|
272
|
+
{/* Mobile Cards */}
|
|
273
|
+
<Box sx={{ display: { xs: "block", md: "none" }, p: 2 }}>
|
|
274
|
+
{filteredAgents.map(agent => <AgentCard key={agent.id} agent={agent} />)}
|
|
275
|
+
</Box>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Success Criteria:
|
|
279
|
+
|
|
280
|
+
#### Manual Verification:
|
|
281
|
+
- [ ] Cards display on mobile, table on desktop
|
|
282
|
+
- [ ] Filters stack vertically on mobile
|
|
283
|
+
- [ ] Card tap selects agent correctly
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Phase 5: Tasks Panel - Table to Cards ✅
|
|
288
|
+
|
|
289
|
+
### Overview
|
|
290
|
+
Same card-based approach as AgentsPanel.
|
|
291
|
+
|
|
292
|
+
### Changes Required:
|
|
293
|
+
|
|
294
|
+
#### TasksPanel.tsx
|
|
295
|
+
|
|
296
|
+
**Create TaskCard component**:
|
|
297
|
+
```tsx
|
|
298
|
+
function TaskCard({ task, selected, onClick, agentName }) {
|
|
299
|
+
return (
|
|
300
|
+
<Box onClick={onClick} sx={{ p: 2, mb: 1, borderRadius: "8px", border: "1px solid" }}>
|
|
301
|
+
<Typography sx={{ fontWeight: 600, mb: 1 }} noWrap>
|
|
302
|
+
{task.task}
|
|
303
|
+
</Typography>
|
|
304
|
+
<Box sx={{ display: "flex", justifyContent: "space-between" }}>
|
|
305
|
+
<StatusBadge status={task.status} />
|
|
306
|
+
<Typography fontSize="0.75rem">{getElapsedTime(task)}</Typography>
|
|
307
|
+
</Box>
|
|
308
|
+
{task.agentId && (
|
|
309
|
+
<Typography fontSize="0.75rem" mt={0.5}>Agent: {agentName}</Typography>
|
|
310
|
+
)}
|
|
311
|
+
</Box>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Apply same conditional rendering as AgentsPanel**
|
|
317
|
+
|
|
318
|
+
### Success Criteria:
|
|
319
|
+
|
|
320
|
+
#### Manual Verification:
|
|
321
|
+
- [ ] Task cards display on mobile
|
|
322
|
+
- [ ] Status and timing visible on cards
|
|
323
|
+
- [ ] Agent name shown when assigned
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Phase 6: Chat Panel - Drawer Sidebar ✅
|
|
328
|
+
|
|
329
|
+
### Overview
|
|
330
|
+
Convert channel list to drawer on mobile.
|
|
331
|
+
|
|
332
|
+
### Changes Required:
|
|
333
|
+
|
|
334
|
+
#### ChatPanel.tsx
|
|
335
|
+
|
|
336
|
+
**Add drawer state**:
|
|
337
|
+
```tsx
|
|
338
|
+
const [channelDrawerOpen, setChannelDrawerOpen] = useState(false);
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Mobile drawer for channels**:
|
|
342
|
+
```tsx
|
|
343
|
+
<Drawer
|
|
344
|
+
open={channelDrawerOpen}
|
|
345
|
+
onClose={() => setChannelDrawerOpen(false)}
|
|
346
|
+
sx={{ display: { xs: "block", md: "none" } }}
|
|
347
|
+
>
|
|
348
|
+
{/* Channel list content */}
|
|
349
|
+
</Drawer>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Desktop permanent sidebar**:
|
|
353
|
+
```tsx
|
|
354
|
+
<Box sx={{
|
|
355
|
+
width: 220,
|
|
356
|
+
display: { xs: "none", md: "flex" },
|
|
357
|
+
}}>
|
|
358
|
+
{/* Channel list content */}
|
|
359
|
+
</Box>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Mobile hamburger button**:
|
|
363
|
+
```tsx
|
|
364
|
+
<IconButton
|
|
365
|
+
sx={{ display: { xs: "flex", md: "none" } }}
|
|
366
|
+
onClick={() => setChannelDrawerOpen(true)}
|
|
367
|
+
>
|
|
368
|
+
<MenuIcon />
|
|
369
|
+
</IconButton>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Thread panel overlay on mobile**:
|
|
373
|
+
```tsx
|
|
374
|
+
{selectedThreadMessage && (
|
|
375
|
+
<Box sx={{
|
|
376
|
+
position: { xs: "fixed", md: "relative" },
|
|
377
|
+
inset: { xs: 0, md: "auto" },
|
|
378
|
+
zIndex: { xs: 1300, md: "auto" },
|
|
379
|
+
}}>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Success Criteria:
|
|
383
|
+
|
|
384
|
+
#### Manual Verification:
|
|
385
|
+
- [ ] Channel list opens as drawer on mobile
|
|
386
|
+
- [ ] Hamburger menu button visible on mobile
|
|
387
|
+
- [ ] Thread view covers full screen on mobile
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Phase 7: StatsBar - Compact Mobile Layout ✅
|
|
392
|
+
|
|
393
|
+
### Overview
|
|
394
|
+
Reduce hexagon sizes and enable horizontal scroll on mobile.
|
|
395
|
+
|
|
396
|
+
### Changes Required:
|
|
397
|
+
|
|
398
|
+
#### StatsBar.tsx
|
|
399
|
+
|
|
400
|
+
**Smaller hexagons**:
|
|
401
|
+
```tsx
|
|
402
|
+
<Box sx={{
|
|
403
|
+
width: { xs: 65, sm: 75, md: 90 },
|
|
404
|
+
height: { xs: 72, sm: 84, md: 100 },
|
|
405
|
+
}}>
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Smaller value text**:
|
|
409
|
+
```tsx
|
|
410
|
+
<Typography sx={{
|
|
411
|
+
fontSize: { xs: "1.1rem", md: "1.5rem" },
|
|
412
|
+
}}>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Horizontal scroll container**:
|
|
416
|
+
```tsx
|
|
417
|
+
<Box sx={{
|
|
418
|
+
flexDirection: { xs: "row", md: "column" },
|
|
419
|
+
overflowX: { xs: "auto", md: "visible" },
|
|
420
|
+
gap: { xs: 1, md: 0 },
|
|
421
|
+
}}>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Success Criteria:
|
|
425
|
+
|
|
426
|
+
#### Manual Verification:
|
|
427
|
+
- [ ] Stats fit on mobile screen
|
|
428
|
+
- [ ] Horizontal scroll works on mobile
|
|
429
|
+
- [ ] Values readable on small screens
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Phase 8: Touch Target Sizing ✅
|
|
434
|
+
|
|
435
|
+
### Overview
|
|
436
|
+
Ensure all interactive elements meet 44x44px minimum tap target.
|
|
437
|
+
|
|
438
|
+
### Changes Required:
|
|
439
|
+
|
|
440
|
+
Apply to all IconButtons and clickable elements:
|
|
441
|
+
```tsx
|
|
442
|
+
sx={{
|
|
443
|
+
minWidth: { xs: 44, md: "auto" },
|
|
444
|
+
minHeight: { xs: 44, md: "auto" },
|
|
445
|
+
}}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Files to update:
|
|
449
|
+
- Header.tsx (theme toggle, settings button)
|
|
450
|
+
- AgentsPanel.tsx (refresh button)
|
|
451
|
+
- TasksPanel.tsx (filter dropdowns)
|
|
452
|
+
- ChatPanel.tsx (send button, menu buttons)
|
|
453
|
+
- All detail panels (close/expand buttons)
|
|
454
|
+
|
|
455
|
+
### Success Criteria:
|
|
456
|
+
|
|
457
|
+
#### Manual Verification:
|
|
458
|
+
- [ ] All buttons tappable without precision
|
|
459
|
+
- [ ] No overlapping tap targets
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## Testing Strategy
|
|
464
|
+
|
|
465
|
+
### Device Testing:
|
|
466
|
+
1. Chrome DevTools responsive mode
|
|
467
|
+
2. iPhone SE (320px) - smallest viewport
|
|
468
|
+
3. iPhone 14 (390px) - common phone
|
|
469
|
+
4. iPad Mini (768px) - small tablet
|
|
470
|
+
5. iPad (1024px) - tablet
|
|
471
|
+
|
|
472
|
+
### Manual Testing Steps:
|
|
473
|
+
1. Navigate all tabs on each viewport
|
|
474
|
+
2. Select and view agent/task details
|
|
475
|
+
3. Use chat with channel switching
|
|
476
|
+
4. Verify all buttons tappable
|
|
477
|
+
5. Check for horizontal overflow
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Files Summary
|
|
482
|
+
|
|
483
|
+
| File | Priority | Changes |
|
|
484
|
+
|------|----------|---------|
|
|
485
|
+
| `ui/src/components/Dashboard.tsx` | 1 | Layout orchestration |
|
|
486
|
+
| `ui/src/components/Header.tsx` | 2 | Padding/sizing |
|
|
487
|
+
| `ui/src/components/AgentDetailPanel.tsx` | 3 | Full-screen overlay |
|
|
488
|
+
| `ui/src/components/TaskDetailPanel.tsx` | 3 | Full-screen overlay |
|
|
489
|
+
| `ui/src/components/AgentsPanel.tsx` | 4 | Table-to-cards |
|
|
490
|
+
| `ui/src/components/TasksPanel.tsx` | 4 | Table-to-cards |
|
|
491
|
+
| `ui/src/components/ChatPanel.tsx` | 5 | Drawer sidebar |
|
|
492
|
+
| `ui/src/components/StatsBar.tsx` | 6 | Compact layout |
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## References
|
|
497
|
+
|
|
498
|
+
- MUI Joy breakpoints: Default `xs: 0, sm: 600, md: 900, lg: 1200, xl: 1536`
|
|
499
|
+
- MUI sx prop: https://mui.com/system/getting-started/the-sx-prop/
|
|
500
|
+
- Touch target guidelines: 44x44px minimum (Apple HIG)
|
|
501
|
+
- Current theme: `ui/src/lib/theme.ts`
|