apteva 0.4.41 → 0.4.44

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 (102) hide show
  1. package/dist/ActivityPage.c48n83h2.js +3 -0
  2. package/dist/ApiDocsPage.yzcxx5ax.js +4 -0
  3. package/dist/App.09yb8t0b.js +1 -0
  4. package/dist/App.152mbs1r.js +4 -0
  5. package/dist/App.3a67nx9w.js +4 -0
  6. package/dist/App.9epx6785.js +4 -0
  7. package/dist/App.d8955awp.js +4 -0
  8. package/dist/App.drwb57jq.js +4 -0
  9. package/dist/App.gssbmajb.js +4 -0
  10. package/dist/App.qw70pc29.js +53 -0
  11. package/dist/{App.7fb3e7mp.js → App.qzbx5wtj.js} +1 -1
  12. package/dist/App.r5serxkt.js +8 -0
  13. package/dist/App.tpmp9020.js +20 -0
  14. package/dist/App.v2wb4d7d.js +61 -0
  15. package/dist/App.vxmaaj0m.js +13 -0
  16. package/dist/App.w4p2tda9.js +4 -0
  17. package/dist/App.wv2ng55q.js +221 -0
  18. package/dist/App.yncnrn0f.js +4 -0
  19. package/dist/ConnectionsPage.k6cspyqq.js +3 -0
  20. package/dist/McpPage.cdxm48xj.js +3 -0
  21. package/dist/SettingsPage.evpv7c2y.js +3 -0
  22. package/dist/SkillsPage.pvzp6c1a.js +3 -0
  23. package/dist/TasksPage.6jnvbpsy.js +3 -0
  24. package/dist/TelemetryPage.t7vk24zc.js +3 -0
  25. package/dist/TestsPage.5x6658aa.js +3 -0
  26. package/dist/ThreadsPage.3fvhtevh.js +3 -0
  27. package/dist/apteva-kit.css +1 -1
  28. package/dist/index.html +1 -1
  29. package/dist/styles.css +1 -1
  30. package/package.json +8 -8
  31. package/src/db.ts +19 -9
  32. package/src/integrations/agentdojo.ts +1 -0
  33. package/src/mcp-platform.ts +418 -63
  34. package/src/openapi.ts +96 -0
  35. package/src/providers.ts +50 -24
  36. package/src/routes/api/agent-utils.ts +0 -1
  37. package/src/routes/api/agents.ts +19 -1
  38. package/src/routes/api/meta-agent.ts +2 -0
  39. package/src/routes/api/system.ts +90 -1
  40. package/src/routes/api/telemetry.ts +19 -1
  41. package/src/routes/share.ts +85 -0
  42. package/src/server.ts +12 -0
  43. package/src/web/App.tsx +89 -11
  44. package/src/web/components/activity/ActivityPage.tsx +14 -14
  45. package/src/web/components/agents/AgentCard.tsx +14 -14
  46. package/src/web/components/agents/AgentPanel.tsx +358 -198
  47. package/src/web/components/agents/AgentsView.tsx +4 -4
  48. package/src/web/components/agents/CreateAgentModal.tsx +21 -79
  49. package/src/web/components/api/ApiDocsPage.tsx +66 -66
  50. package/src/web/components/auth/CreateAccountStep.tsx +16 -16
  51. package/src/web/components/auth/LoginPage.tsx +10 -10
  52. package/src/web/components/common/LoadingSpinner.tsx +2 -2
  53. package/src/web/components/common/Modal.tsx +8 -8
  54. package/src/web/components/common/Select.tsx +9 -9
  55. package/src/web/components/connections/ConnectionsPage.tsx +4 -4
  56. package/src/web/components/connections/IntegrationsTab.tsx +18 -18
  57. package/src/web/components/connections/OverviewTab.tsx +13 -13
  58. package/src/web/components/connections/TriggersTab.tsx +99 -99
  59. package/src/web/components/dashboard/Dashboard.tsx +32 -32
  60. package/src/web/components/layout/Header.tsx +50 -34
  61. package/src/web/components/layout/Sidebar.tsx +34 -15
  62. package/src/web/components/mcp/IntegrationsPanel.tsx +40 -40
  63. package/src/web/components/mcp/McpPage.tsx +208 -208
  64. package/src/web/components/meta-agent/MetaAgent.tsx +12 -10
  65. package/src/web/components/onboarding/OnboardingWizard.tsx +25 -25
  66. package/src/web/components/settings/SettingsPage.tsx +258 -175
  67. package/src/web/components/skills/SkillsPage.tsx +88 -88
  68. package/src/web/components/tasks/TasksPage.tsx +339 -54
  69. package/src/web/components/telemetry/TelemetryPage.tsx +135 -64
  70. package/src/web/components/tests/TestsPage.tsx +50 -50
  71. package/src/web/components/threads/ThreadsPage.tsx +23 -21
  72. package/src/web/context/ProjectContext.tsx +6 -1
  73. package/src/web/context/ThemeContext.tsx +69 -0
  74. package/src/web/context/index.ts +2 -0
  75. package/src/web/styles.css +5 -3
  76. package/src/web/themes.ts +99 -0
  77. package/src/web/types.ts +0 -4
  78. package/dist/ActivityPage.7907h64p.js +0 -3
  79. package/dist/ApiDocsPage.k3jjenpq.js +0 -4
  80. package/dist/App.01nq20st.js +0 -4
  81. package/dist/App.1maqvamf.js +0 -4
  82. package/dist/App.2yjrh32f.js +0 -4
  83. package/dist/App.3qw8nben.js +0 -20
  84. package/dist/App.7sy3wq8c.js +0 -4
  85. package/dist/App.apjrmctz.js +0 -57
  86. package/dist/App.av6t2yhe.js +0 -4
  87. package/dist/App.jqj5a094.js +0 -46
  88. package/dist/App.mc7xf85h.js +0 -4
  89. package/dist/App.myxqcj9x.js +0 -4
  90. package/dist/App.nm91r1mp.js +0 -13
  91. package/dist/App.p02f4ret.js +0 -1
  92. package/dist/App.qcknavjz.js +0 -221
  93. package/dist/App.vc7vfhg4.js +0 -4
  94. package/dist/App.z4s9zkw5.js +0 -4
  95. package/dist/ConnectionsPage.z1pw5xe2.js +0 -3
  96. package/dist/McpPage.8vc97z0b.js +0 -3
  97. package/dist/SettingsPage.p61bz8kd.js +0 -3
  98. package/dist/SkillsPage.r9x43g3g.js +0 -3
  99. package/dist/TasksPage.1e0zkye4.js +0 -3
  100. package/dist/TelemetryPage.p9vbe4gf.js +0 -3
  101. package/dist/TestsPage.d4xy504e.js +0 -3
  102. package/dist/ThreadsPage.m016am3x.js +0 -3
@@ -149,7 +149,7 @@ export function Dashboard({
149
149
  <StatCard label="Agents" value={filteredAgents.length} subValue={`${filteredRunningCount} running`} />
150
150
  <StatCard label="Tasks" value={taskStats.total} subValue={`${taskStats.pending} pending`} />
151
151
  <StatCard label="Completed" value={taskStats.completed} color="text-green-400" />
152
- <StatCard label="Providers" value={configuredProviders.length} color="text-[#f97316]" />
152
+ <StatCard label="Providers" value={configuredProviders.length} color="text-[var(--color-accent)]" />
153
153
  </div>
154
154
 
155
155
  <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
@@ -160,11 +160,11 @@ export function Dashboard({
160
160
  onAction={() => onNavigate("agents")}
161
161
  >
162
162
  {loading ? (
163
- <div className="p-4 text-center text-[#666]">Loading...</div>
163
+ <div className="p-4 text-center text-[var(--color-text-muted)]">Loading...</div>
164
164
  ) : filteredAgents.length === 0 ? (
165
- <div className="p-4 text-center text-[#666]">No agents yet</div>
165
+ <div className="p-4 text-center text-[var(--color-text-muted)]">No agents yet</div>
166
166
  ) : (
167
- <div className="divide-y divide-[#1a1a1a]">
167
+ <div className="divide-y divide-[var(--color-border)]">
168
168
  {filteredAgents.slice(0, 5).map((agent) => (
169
169
  <AgentListItem
170
170
  key={agent.id}
@@ -185,12 +185,12 @@ export function Dashboard({
185
185
  onAction={() => onNavigate("telemetry")}
186
186
  >
187
187
  {activities.length === 0 ? (
188
- <div className="p-4 text-center text-[#666]">
188
+ <div className="p-4 text-center text-[var(--color-text-muted)]">
189
189
  <p>No activity yet</p>
190
- <p className="text-sm text-[#444] mt-1">Agent activity will appear here in real-time</p>
190
+ <p className="text-sm text-[var(--color-text-faint)] mt-1">Agent activity will appear here in real-time</p>
191
191
  </div>
192
192
  ) : (
193
- <div className="divide-y divide-[#1a1a1a]">
193
+ <div className="divide-y divide-[var(--color-border)]">
194
194
  {activities.map((evt) => (
195
195
  <ActivityItem
196
196
  key={evt.id}
@@ -210,12 +210,12 @@ export function Dashboard({
210
210
  onAction={() => onNavigate("tasks")}
211
211
  >
212
212
  {filteredTasks.length === 0 ? (
213
- <div className="p-4 text-center text-[#666]">
213
+ <div className="p-4 text-center text-[var(--color-text-muted)]">
214
214
  <p>No tasks yet</p>
215
- <p className="text-sm text-[#444] mt-1">Tasks will appear when agents create them</p>
215
+ <p className="text-sm text-[var(--color-text-faint)] mt-1">Tasks will appear when agents create them</p>
216
216
  </div>
217
217
  ) : (
218
- <div className="divide-y divide-[#1a1a1a]">
218
+ <div className="divide-y divide-[var(--color-border)]">
219
219
  {filteredTasks.slice(0, 5).map((task) => (
220
220
  <div
221
221
  key={`${task.agentId}-${task.id}`}
@@ -223,16 +223,16 @@ export function Dashboard({
223
223
  >
224
224
  <div className="flex-1 min-w-0">
225
225
  <p className="font-medium truncate">{task.title}</p>
226
- <p className="text-sm text-[#666]">
226
+ <p className="text-sm text-[var(--color-text-muted)]">
227
227
  {task.agentName}
228
228
  {task.recurrence && (
229
- <span className="ml-1 text-[#555]">· {formatCronShort(task.recurrence)}</span>
229
+ <span className="ml-1 text-[var(--color-text-faint)]">· {formatCronShort(task.recurrence)}</span>
230
230
  )}
231
231
  {task.next_run && (
232
- <span className="ml-1 text-[#f97316]">· {formatRelativeShort(task.next_run)}</span>
232
+ <span className="ml-1 text-[var(--color-accent)]">· {formatRelativeShort(task.next_run)}</span>
233
233
  )}
234
234
  {!task.next_run && task.execute_at && (
235
- <span className="ml-1 text-[#f97316]">· {formatRelativeShort(task.execute_at)}</span>
235
+ <span className="ml-1 text-[var(--color-accent)]">· {formatRelativeShort(task.execute_at)}</span>
236
236
  )}
237
237
  </p>
238
238
  </div>
@@ -264,10 +264,10 @@ interface StatCardProps {
264
264
 
265
265
  function StatCard({ label, value, subValue, color }: StatCardProps) {
266
266
  return (
267
- <div className="bg-[#111] rounded p-4 border border-[#1a1a1a]">
268
- <p className="text-sm text-[#666] mb-1">{label}</p>
267
+ <div className="bg-[var(--color-surface)] rounded p-4 border border-[var(--color-border)]">
268
+ <p className="text-sm text-[var(--color-text-muted)] mb-1">{label}</p>
269
269
  <p className={`text-2xl font-semibold ${color || ''}`}>{value}</p>
270
- {subValue && <p className="text-xs text-[#555] mt-1">{subValue}</p>}
270
+ {subValue && <p className="text-xs text-[var(--color-text-faint)] mt-1">{subValue}</p>}
271
271
  </div>
272
272
  );
273
273
  }
@@ -281,8 +281,8 @@ interface DashboardCardProps {
281
281
 
282
282
  function DashboardCard({ title, actionLabel, onAction, children }: DashboardCardProps) {
283
283
  return (
284
- <div className="bg-[#111] rounded border border-[#1a1a1a] overflow-hidden">
285
- <div className="px-4 py-3 border-b border-[#1a1a1a] flex items-center justify-between">
284
+ <div className="bg-[var(--color-surface)] rounded border border-[var(--color-border)] overflow-hidden">
285
+ <div className="px-4 py-3 border-b border-[var(--color-border)] flex items-center justify-between">
286
286
  <h3 className="font-semibold">{title}</h3>
287
287
  <button
288
288
  onClick={onAction}
@@ -304,7 +304,7 @@ function AgentListItem({ agent, onSelect, onMessage, showProject }: { agent: Age
304
304
  return (
305
305
  <div
306
306
  onClick={onSelect}
307
- className="px-4 py-3 hover:bg-[#1a1a1a] cursor-pointer flex items-center justify-between group"
307
+ className="px-4 py-3 hover:bg-[var(--color-surface-raised)] cursor-pointer flex items-center justify-between group"
308
308
  >
309
309
  <div className="flex items-center gap-3 flex-1 min-w-0">
310
310
  <span
@@ -313,12 +313,12 @@ function AgentListItem({ agent, onSelect, onMessage, showProject }: { agent: Age
313
313
  ? isActive
314
314
  ? "bg-green-400 animate-pulse"
315
315
  : "bg-[#3b82f6]"
316
- : "bg-[#444]"
316
+ : "bg-[var(--color-scrollbar)]"
317
317
  }`}
318
318
  />
319
319
  <div className="flex-1 min-w-0">
320
320
  <p className="font-medium truncate">{agent.name}</p>
321
- <div className="flex items-center gap-2 text-sm text-[#666]">
321
+ <div className="flex items-center gap-2 text-sm text-[var(--color-text-muted)]">
322
322
  {isActive && label ? (
323
323
  <span className="text-green-400 truncate">{label}</span>
324
324
  ) : (
@@ -326,7 +326,7 @@ function AgentListItem({ agent, onSelect, onMessage, showProject }: { agent: Age
326
326
  )}
327
327
  {showProject && project && (
328
328
  <>
329
- <span className="text-[#444]">·</span>
329
+ <span className="text-[var(--color-text-faint)]">·</span>
330
330
  <span className="flex items-center gap-1">
331
331
  <span className="w-2 h-2 rounded-full" style={{ backgroundColor: project.color }} />
332
332
  {project.name}
@@ -339,7 +339,7 @@ function AgentListItem({ agent, onSelect, onMessage, showProject }: { agent: Age
339
339
  {onMessage && (
340
340
  <button
341
341
  onClick={(e) => { e.stopPropagation(); onMessage(); }}
342
- className="opacity-0 group-hover:opacity-100 transition px-2 py-1 text-xs text-[#f97316] hover:bg-[#f97316]/10 rounded"
342
+ className="opacity-0 group-hover:opacity-100 transition px-2 py-1 text-xs text-[var(--color-accent)] hover:bg-[var(--color-accent-10)] rounded"
343
343
  title="Send message"
344
344
  >
345
345
  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -367,9 +367,9 @@ function ActivityItem({ activity, agentName, timestamp }: { activity: string; ag
367
367
  return (
368
368
  <div className="px-4 py-3">
369
369
  <p className="text-sm truncate">{activity}</p>
370
- <div className="flex items-center gap-2 text-xs text-[#555] mt-1">
371
- <span className="text-[#666]">{agentName}</span>
372
- <span className="text-[#444]">&middot;</span>
370
+ <div className="flex items-center gap-2 text-xs text-[var(--color-text-faint)] mt-1">
371
+ <span className="text-[var(--color-text-muted)]">{agentName}</span>
372
+ <span className="text-[var(--color-text-faint)]">&middot;</span>
373
373
  <span>{timeAgo(timestamp)}</span>
374
374
  </div>
375
375
  </div>
@@ -428,13 +428,13 @@ function QuickMessageModal({ agent, onClose }: { agent: Agent; onClose: () => vo
428
428
  return (
429
429
  <div className="fixed inset-0 z-50 flex items-center justify-center">
430
430
  <div className="absolute inset-0 bg-black/60" onClick={onClose} />
431
- <div className="relative bg-[#111] border border-[#222] rounded-xl shadow-2xl w-full max-w-md mx-4 p-5">
431
+ <div className="relative bg-[var(--color-surface)] border border-[var(--color-border-light)] rounded-xl shadow-2xl w-full max-w-md mx-4 p-5">
432
432
  <div className="flex items-center justify-between mb-4">
433
433
  <div className="flex items-center gap-3">
434
434
  <span className="w-2.5 h-2.5 rounded-full bg-green-400 animate-pulse" />
435
435
  <h3 className="font-medium">{agent.name}</h3>
436
436
  </div>
437
- <button onClick={onClose} className="text-[#666] hover:text-[#e0e0e0] transition">
437
+ <button onClick={onClose} className="text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition">
438
438
  <CloseIcon />
439
439
  </button>
440
440
  </div>
@@ -442,7 +442,7 @@ function QuickMessageModal({ agent, onClose }: { agent: Agent; onClose: () => vo
442
442
  {sent ? (
443
443
  <div className="py-6 text-center">
444
444
  <p className="text-green-400 font-medium">Message sent</p>
445
- <p className="text-sm text-[#555] mt-1">The agent will process your message</p>
445
+ <p className="text-sm text-[var(--color-text-faint)] mt-1">The agent will process your message</p>
446
446
  </div>
447
447
  ) : (
448
448
  <div className="flex gap-2">
@@ -454,12 +454,12 @@ function QuickMessageModal({ agent, onClose }: { agent: Agent; onClose: () => vo
454
454
  onKeyDown={e => e.key === "Enter" && handleSend()}
455
455
  placeholder={`Message ${agent.name}...`}
456
456
  disabled={sending}
457
- className="flex-1 bg-[#0a0a0a] border border-[#222] rounded-lg px-3 py-2.5 text-sm focus:outline-none focus:border-[#f97316] placeholder-[#444] disabled:opacity-50"
457
+ className="flex-1 bg-[var(--color-bg)] border border-[var(--color-border-light)] rounded-lg px-3 py-2.5 text-sm focus:outline-none focus:border-[var(--color-accent)] placeholder-[#444] disabled:opacity-50"
458
458
  />
459
459
  <button
460
460
  onClick={handleSend}
461
461
  disabled={sending || !message.trim()}
462
- className="px-4 py-2.5 bg-[#f97316] text-black rounded-lg text-sm font-medium hover:bg-[#fb923c] transition disabled:opacity-30"
462
+ className="px-4 py-2.5 bg-[var(--color-accent)] text-black rounded-lg text-sm font-medium hover:bg-[var(--color-accent-hover)] transition disabled:opacity-30"
463
463
  >
464
464
  {sending ? "..." : "Send"}
465
465
  </button>
@@ -134,24 +134,25 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
134
134
  };
135
135
 
136
136
  const getProjectColor = () => {
137
- if (currentProjectId === null) return "#666";
138
- if (currentProjectId === "unassigned") return "#888";
137
+ if (currentProjectId === null) return "var(--color-text-muted)";
138
+ if (currentProjectId === "unassigned") return "var(--color-text-secondary)";
139
139
  return currentProject?.color || "#6366f1";
140
140
  };
141
141
 
142
142
  return (
143
- <header className="border-b border-[#1a1a1a] px-4 md:px-6 py-4 flex-shrink-0">
143
+ <header className="px-4 md:px-6 py-4 flex-shrink-0" style={{ borderBottom: "1px solid var(--color-border)" }}>
144
144
  <div className="flex items-center justify-between">
145
145
  <div className="flex items-center gap-3">
146
146
  {/* Hamburger menu button - mobile only */}
147
147
  <button
148
148
  onClick={onMenuClick}
149
- className="p-2 -ml-2 text-[#666] hover:text-[#e0e0e0] transition md:hidden"
149
+ className="p-2 -ml-2 transition md:hidden"
150
+ style={{ color: "var(--color-text-muted)" }}
150
151
  >
151
152
  <MenuIcon />
152
153
  </button>
153
154
  <div className="flex items-center gap-2">
154
- <span className="text-[#f97316]">&gt;_</span>
155
+ <span style={{ color: "var(--color-accent)" }}>&gt;_</span>
155
156
  <span className="text-xl tracking-wider">apteva</span>
156
157
  </div>
157
158
 
@@ -160,7 +161,8 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
160
161
  <div className="relative ml-2 md:ml-4">
161
162
  <button
162
163
  onClick={() => setShowProjectMenu(!showProjectMenu)}
163
- className="flex items-center gap-2 px-3 py-1.5 rounded border border-[#222] bg-[#111] hover:bg-[#1a1a1a] transition text-sm"
164
+ className="flex items-center gap-2 px-3 py-1.5 rounded transition text-sm"
165
+ style={{ border: "1px solid var(--color-border-light)", backgroundColor: "var(--color-surface)" }}
164
166
  >
165
167
  <span
166
168
  className="w-2.5 h-2.5 rounded-full"
@@ -172,43 +174,49 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
172
174
  <ChevronDownIcon />
173
175
  </button>
174
176
  {showProjectMenu && (
175
- <div className="absolute left-0 top-full mt-1 w-56 bg-[#111] border border-[#222] rounded-lg shadow-xl z-50">
177
+ <div className="absolute left-0 top-full mt-1 w-56 rounded-lg shadow-xl z-50" style={{ backgroundColor: "var(--color-surface)", border: "1px solid var(--color-border-light)" }}>
176
178
  <div className="py-1 max-h-64 overflow-y-auto">
177
179
  <button
178
180
  onClick={() => handleProjectSelect(null)}
179
- className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
180
- currentProjectId === null ? "bg-[#1a1a1a] text-[#f97316]" : ""
181
- }`}
181
+ className="w-full px-4 py-2 text-left text-sm flex items-center gap-2 transition"
182
+ style={{
183
+ backgroundColor: currentProjectId === null ? "var(--color-surface-raised)" : "transparent",
184
+ color: currentProjectId === null ? "var(--color-accent)" : "var(--color-text)",
185
+ }}
182
186
  >
183
- <span className="w-2.5 h-2.5 rounded-full bg-[#666]" />
187
+ <span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: "var(--color-text-muted)" }} />
184
188
  All Projects
185
189
  </button>
186
190
  {projects.map(project => (
187
191
  <button
188
192
  key={project.id}
189
193
  onClick={() => handleProjectSelect(project.id)}
190
- className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
191
- currentProjectId === project.id ? "bg-[#1a1a1a] text-[#f97316]" : ""
192
- }`}
194
+ className="w-full px-4 py-2 text-left text-sm flex items-center gap-2 transition"
195
+ style={{
196
+ backgroundColor: currentProjectId === project.id ? "var(--color-surface-raised)" : "transparent",
197
+ color: currentProjectId === project.id ? "var(--color-accent)" : "var(--color-text)",
198
+ }}
193
199
  >
194
200
  <span
195
201
  className="w-2.5 h-2.5 rounded-full flex-shrink-0"
196
202
  style={{ backgroundColor: project.color }}
197
203
  />
198
204
  <span className="truncate">{project.name}</span>
199
- <span className="ml-auto text-xs text-[#666]">{project.agentCount}</span>
205
+ <span className="ml-auto text-xs" style={{ color: "var(--color-text-muted)" }}>{project.agentCount}</span>
200
206
  </button>
201
207
  ))}
202
208
  {unassignedCount > 0 && (
203
209
  <button
204
210
  onClick={() => handleProjectSelect("unassigned")}
205
- className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
206
- currentProjectId === "unassigned" ? "bg-[#1a1a1a] text-[#f97316]" : ""
207
- }`}
211
+ className="w-full px-4 py-2 text-left text-sm flex items-center gap-2 transition"
212
+ style={{
213
+ backgroundColor: currentProjectId === "unassigned" ? "var(--color-surface-raised)" : "transparent",
214
+ color: currentProjectId === "unassigned" ? "var(--color-accent)" : "var(--color-text)",
215
+ }}
208
216
  >
209
- <span className="w-2.5 h-2.5 rounded-full bg-[#888]" />
217
+ <span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: "var(--color-text-secondary)" }} />
210
218
  <span className="truncate">Unassigned</span>
211
- <span className="ml-auto text-xs text-[#666]">{unassignedCount}</span>
219
+ <span className="ml-auto text-xs" style={{ color: "var(--color-text-muted)" }}>{unassignedCount}</span>
212
220
  </button>
213
221
  )}
214
222
  </div>
@@ -222,7 +230,7 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
222
230
  <span
223
231
  className={`w-2 h-2 rounded-full ${connected ? "bg-green-400" : "bg-red-400"}`}
224
232
  />
225
- <span className="text-xs text-[#666] hidden sm:inline">
233
+ <span className="text-xs hidden sm:inline" style={{ color: "var(--color-text-muted)" }}>
226
234
  {connected ? "Live" : "Offline"}
227
235
  </span>
228
236
  </div>
@@ -230,7 +238,8 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
230
238
  <div className="relative">
231
239
  <button
232
240
  onClick={openNotifications}
233
- className="relative p-2 text-[#666] hover:text-[#e0e0e0] transition rounded hover:bg-[#1a1a1a]"
241
+ className="relative p-2 transition rounded"
242
+ style={{ color: "var(--color-text-muted)" }}
234
243
  >
235
244
  <BellIcon className="w-5 h-5" />
236
245
  {unseenCount > 0 && (
@@ -253,40 +262,47 @@ export function Header({ onMenuClick, agents = [] }: HeaderProps) {
253
262
  {showNotifications && (
254
263
  <>
255
264
  <div className="fixed inset-0 z-40" onClick={() => setShowNotifications(false)} />
256
- <div className="absolute right-0 top-full mt-1 w-80 bg-[#111] border border-[#222] rounded-lg shadow-xl z-50 max-h-96 overflow-y-auto">
257
- <div className="px-4 py-3 border-b border-[#222] flex items-center justify-between">
265
+ <div className="absolute right-0 top-full mt-1 w-80 rounded-lg shadow-xl z-50 max-h-96 overflow-y-auto" style={{ backgroundColor: "var(--color-surface)", border: "1px solid var(--color-border-light)" }}>
266
+ <div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom: "1px solid var(--color-border-light)" }}>
258
267
  <span className="text-sm font-medium">Notifications</span>
259
268
  {notifications.length > 0 && (
260
- <span className="text-xs text-[#666]">{notifications.length} recent</span>
269
+ <span className="text-xs" style={{ color: "var(--color-text-muted)" }}>{notifications.length} recent</span>
261
270
  )}
262
271
  </div>
263
272
  {notifications.length === 0 ? (
264
- <div className="px-4 py-8 text-center text-sm text-[#666]">
273
+ <div className="px-4 py-8 text-center text-sm" style={{ color: "var(--color-text-muted)" }}>
265
274
  No notifications
266
275
  </div>
267
276
  ) : (
268
277
  <div className="py-1">
269
278
  {notifications.map(n => (
270
- <div key={n.id} className={`px-4 py-3 hover:bg-[#1a1a1a] transition border-b border-[#1a1a1a] ${!n.seen ? "bg-[#0f0f0f]" : ""}`}>
279
+ <div key={n.id} className="px-4 py-3 transition" style={{
280
+ borderBottom: "1px solid var(--color-border)",
281
+ backgroundColor: !n.seen ? "var(--color-bg-secondary)" : "transparent",
282
+ }}>
271
283
  <div className="flex items-center gap-2 mb-1">
272
284
  <span className={`w-2 h-2 rounded-full flex-shrink-0 ${
273
285
  !n.seen
274
- ? (n.level === "error" || n.category === "ERROR" ? "bg-red-400" : "bg-[#f97316]")
275
- : "bg-[#333]"
276
- }`} />
277
- <span className={`text-xs font-medium truncate ${!n.seen ? "text-[#ccc]" : "text-[#666]"}`}>
286
+ ? (n.level === "error" || n.category === "ERROR" ? "bg-red-400" : "")
287
+ : ""
288
+ }`} style={{
289
+ backgroundColor: !n.seen
290
+ ? (n.level === "error" || n.category === "ERROR" ? undefined : "var(--color-accent)")
291
+ : "var(--color-surface-raised)",
292
+ }} />
293
+ <span className="text-xs font-medium truncate" style={{ color: !n.seen ? "var(--color-text)" : "var(--color-text-muted)" }}>
278
294
  {n.category === "system" && n.type === "agent_stopped" ? "Agent Stopped" :
279
295
  n.category === "ERROR" ? "Error" :
280
296
  `${n.category} / ${n.type}`}
281
297
  </span>
282
- <span className="text-[10px] text-[#555] ml-auto flex-shrink-0">
298
+ <span className="text-[10px] ml-auto flex-shrink-0" style={{ color: "var(--color-text-faint)" }}>
283
299
  {formatNotifTime(n.timestamp)}
284
300
  </span>
285
301
  </div>
286
- <div className={`text-xs truncate ${!n.seen ? "text-[#aaa]" : "text-[#666]"}`}>
302
+ <div className="text-xs truncate" style={{ color: !n.seen ? "var(--color-text-secondary)" : "var(--color-text-muted)" }}>
287
303
  {n.error || (n.data as any)?.message || (n.data as any)?.error || `${n.type} event`}
288
304
  </div>
289
- <div className="text-[10px] text-[#555] mt-1">
305
+ <div className="text-[10px] mt-1" style={{ color: "var(--color-text-faint)" }}>
290
306
  {agentNames[n.agent_id] || n.agent_id.slice(0, 8)}
291
307
  </div>
292
308
  </div>
@@ -39,20 +39,22 @@ export function Sidebar({ route, agentCount, taskCount, onNavigate, isOpen, onCl
39
39
  {/* Sidebar - hidden on mobile unless open, always visible on md+ */}
40
40
  <aside
41
41
  className={`
42
- fixed inset-y-0 left-0 z-50 w-64 bg-[#0a0a0a] border-r border-[#1a1a1a] p-4 flex flex-col transform transition-transform duration-200 ease-in-out
42
+ fixed inset-y-0 left-0 z-50 w-64 p-4 flex flex-col transform transition-transform duration-200 ease-in-out
43
43
  md:relative md:w-56 md:translate-x-0 md:z-auto
44
44
  ${isOpen ? "translate-x-0" : "-translate-x-full"}
45
45
  `}
46
+ style={{ backgroundColor: "var(--color-bg)", borderRight: "1px solid var(--color-border)" }}
46
47
  >
47
48
  {/* Mobile header with close button */}
48
49
  <div className="flex items-center justify-between mb-4 md:hidden">
49
50
  <div className="flex items-center gap-2">
50
- <span className="text-[#f97316]">&gt;_</span>
51
+ <span style={{ color: "var(--color-accent)" }}>&gt;_</span>
51
52
  <span className="text-lg tracking-wider">apteva</span>
52
53
  </div>
53
54
  <button
54
55
  onClick={onClose}
55
- className="p-2 text-[#666] hover:text-[#e0e0e0] transition"
56
+ className="p-2 transition"
57
+ style={{ color: "var(--color-text-muted)" }}
56
58
  >
57
59
  <CloseIcon />
58
60
  </button>
@@ -137,26 +139,31 @@ export function Sidebar({ route, agentCount, taskCount, onNavigate, isOpen, onCl
137
139
 
138
140
  {/* User profile - pinned to bottom */}
139
141
  {user && (
140
- <div className="relative border-t border-[#1a1a1a] pt-3 mt-3">
142
+ <div className="relative pt-3 mt-3" style={{ borderTop: "1px solid var(--color-border)" }}>
141
143
  <button
142
144
  onClick={() => setShowUserMenu(!showUserMenu)}
143
- className="w-full flex items-center gap-3 px-3 py-2 rounded hover:bg-[#111] transition"
145
+ className="w-full flex items-center gap-3 px-3 py-2 rounded transition"
146
+ style={{ color: "var(--color-text)" }}
147
+ onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--color-surface)"}
148
+ onMouseLeave={e => e.currentTarget.style.backgroundColor = "transparent"}
144
149
  >
145
- <div className="w-8 h-8 rounded-full bg-[#f97316] flex items-center justify-center text-black font-medium text-sm flex-shrink-0">
150
+ <div className="w-8 h-8 rounded-full flex items-center justify-center text-black font-medium text-sm flex-shrink-0" style={{ backgroundColor: "var(--color-accent)" }}>
146
151
  {user.username.charAt(0).toUpperCase()}
147
152
  </div>
148
153
  <div className="flex-1 min-w-0 text-left">
149
154
  <p className="text-sm font-medium truncate">{user.username}</p>
150
- <p className="text-xs text-[#555]">{user.role}</p>
155
+ <p className="text-xs" style={{ color: "var(--color-text-faint)" }}>{user.role}</p>
151
156
  </div>
152
157
  </button>
153
158
  {showUserMenu && (
154
159
  <>
155
160
  <div className="fixed inset-0 z-40" onClick={() => setShowUserMenu(false)} />
156
- <div className="absolute left-3 bottom-full mb-1 w-48 bg-[#111] border border-[#222] rounded-lg shadow-xl z-50">
161
+ <div className="absolute left-3 bottom-full mb-1 w-48 rounded-lg shadow-xl z-50" style={{ backgroundColor: "var(--color-surface)", border: "1px solid var(--color-border-light)" }}>
157
162
  <button
158
163
  onClick={handleLogout}
159
- className="w-full px-4 py-2.5 text-left text-sm text-red-400 hover:bg-[#1a1a1a] transition rounded-lg"
164
+ className="w-full px-4 py-2.5 text-left text-sm text-red-400 transition rounded-lg"
165
+ onMouseEnter={e => e.currentTarget.style.backgroundColor = "var(--color-surface-raised)"}
166
+ onMouseLeave={e => e.currentTarget.style.backgroundColor = "transparent"}
160
167
  >
161
168
  Sign out
162
169
  </button>
@@ -182,16 +189,28 @@ function NavButton({ icon, label, active, onClick, badge }: NavButtonProps) {
182
189
  return (
183
190
  <button
184
191
  onClick={onClick}
185
- className={`w-full flex items-center gap-3 px-3 py-2 rounded font-medium transition ${
186
- active
187
- ? "bg-[#111] text-[#e0e0e0]"
188
- : "text-[#666] hover:bg-[#111] hover:text-[#888]"
189
- }`}
192
+ className="w-full flex items-center gap-3 px-3 py-2 rounded font-medium transition"
193
+ style={{
194
+ backgroundColor: active ? "var(--color-surface)" : "transparent",
195
+ color: active ? "var(--color-text)" : "var(--color-text-muted)",
196
+ }}
197
+ onMouseEnter={e => {
198
+ if (!active) {
199
+ e.currentTarget.style.backgroundColor = "var(--color-surface)";
200
+ e.currentTarget.style.color = "var(--color-text-secondary)";
201
+ }
202
+ }}
203
+ onMouseLeave={e => {
204
+ if (!active) {
205
+ e.currentTarget.style.backgroundColor = "transparent";
206
+ e.currentTarget.style.color = "var(--color-text-muted)";
207
+ }
208
+ }}
190
209
  >
191
210
  {icon}
192
211
  {label}
193
212
  {badge && (
194
- <span className="ml-auto bg-[#333] text-[#888] text-xs px-2 py-0.5 rounded-full">
213
+ <span className="ml-auto text-xs px-2 py-0.5 rounded-full" style={{ backgroundColor: "var(--color-surface-raised)", color: "var(--color-text-secondary)" }}>
195
214
  {badge}
196
215
  </span>
197
216
  )}