@agenticmail/enterprise 0.5.213 → 0.5.214

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.
@@ -0,0 +1,45 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-NJRHVKVY.js";
18
+ import {
19
+ PROVIDER_REGISTRY,
20
+ listAllProviders,
21
+ resolveApiKeyForProvider,
22
+ resolveProvider
23
+ } from "./chunk-UF3ZJMJO.js";
24
+ import "./chunk-KFQGP6VL.js";
25
+ export {
26
+ AgentRuntime,
27
+ EmailChannel,
28
+ FollowUpScheduler,
29
+ PROVIDER_REGISTRY,
30
+ SessionManager,
31
+ SubAgentManager,
32
+ ToolRegistry,
33
+ callLLM,
34
+ createAgentRuntime,
35
+ createNoopHooks,
36
+ createRuntimeHooks,
37
+ estimateMessageTokens,
38
+ estimateTokens,
39
+ executeTool,
40
+ listAllProviders,
41
+ resolveApiKeyForProvider,
42
+ resolveProvider,
43
+ runAgentLoop,
44
+ toolsToDefinitions
45
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-IP5HZWZM.js";
4
+ import "./chunk-OF4MUWWS.js";
5
+ import "./chunk-UF3ZJMJO.js";
6
+ import "./chunk-3OC6RH7W.js";
7
+ import "./chunk-2DDKGTD6.js";
8
+ import "./chunk-YVK6F5OD.js";
9
+ import "./chunk-MKRNEM5A.js";
10
+ import "./chunk-DRXMYYKN.js";
11
+ import "./chunk-6WSX7QXF.js";
12
+ import "./chunk-KFQGP6VL.js";
13
+ export {
14
+ createServer
15
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-QRRW3LES.js";
10
+ import "./chunk-VQQ4SYYQ.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.213",
3
+ "version": "0.5.214",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,8 +14,10 @@ var PAD = 40;
14
14
  var STATUS_COLORS = { created: '#6366f1', assigned: '#f59e0b', in_progress: '#06b6d4', completed: '#22c55e', failed: '#ef4444', cancelled: '#6b7394' };
15
15
  var PRIORITY_COLORS = { urgent: '#ef4444', high: '#f59e0b', normal: '#6366f1', low: '#6b7394' };
16
16
  var DELEGATION_COLORS = { delegation: '#6366f1', review: '#f59e0b', revision: '#f97316', escalation: '#ef4444', return: '#22c55e' };
17
- var BG = '#0a0c14';
18
- var EDGE_COLOR = 'rgba(255,255,255,0.18)';
17
+ // Theme-aware: use CSS variables where possible, detect dark/light
18
+ function isDark() { try { return window.matchMedia('(prefers-color-scheme: dark)').matches || document.documentElement.classList.contains('dark') || document.body.getAttribute('data-theme') === 'dark'; } catch(e) { return true; } }
19
+ var BG = 'var(--bg-canvas, var(--bg-primary, #0a0c14))';
20
+ var EDGE_COLOR = 'var(--tp-edge, rgba(128,128,128,0.25))';
19
21
  var EDGE_HL = 'rgba(99,102,241,0.7)';
20
22
 
21
23
  // ─── CSS Keyframes (injected once) ──────────────────────
@@ -24,13 +26,15 @@ function injectCSS() {
24
26
  if (_injected) return; _injected = true;
25
27
  var style = document.createElement('style');
26
28
  style.textContent = `
29
+ :root { --tp-bg: #0a0c14; --tp-text: #fff; --tp-text-dim: rgba(255,255,255,0.4); --tp-text-faint: rgba(255,255,255,0.15); --tp-border: rgba(255,255,255,0.08); --tp-card: rgba(255,255,255,0.02); --tp-card-hover: rgba(255,255,255,0.06); --tp-edge: rgba(255,255,255,0.18); --tp-toolbar: rgba(0,0,0,0.3); --tp-metrics: rgba(0,0,0,0.12); }
30
+ [data-theme="light"], .light, :root:not(.dark) { --tp-bg: var(--bg-primary, #f8fafc); --tp-text: var(--text-primary, #1e293b); --tp-text-dim: var(--text-muted, #64748b); --tp-text-faint: rgba(0,0,0,0.06); --tp-border: var(--border, rgba(0,0,0,0.08)); --tp-card: rgba(0,0,0,0.02); --tp-card-hover: rgba(0,0,0,0.05); --tp-edge: rgba(0,0,0,0.2); --tp-toolbar: rgba(0,0,0,0.03); --tp-metrics: rgba(0,0,0,0.02); }
31
+ @media (prefers-color-scheme: light) { :root:not(.dark) { --tp-bg: var(--bg-primary, #f8fafc); --tp-text: var(--text-primary, #1e293b); --tp-text-dim: var(--text-muted, #64748b); --tp-text-faint: rgba(0,0,0,0.06); --tp-border: var(--border, rgba(0,0,0,0.08)); --tp-card: rgba(0,0,0,0.02); --tp-card-hover: rgba(0,0,0,0.05); --tp-edge: rgba(0,0,0,0.2); --tp-toolbar: rgba(0,0,0,0.03); --tp-metrics: rgba(0,0,0,0.02); } }
27
32
  @keyframes flowDash { to { stroke-dashoffset: -24; } }
28
33
  @keyframes flowPulse { 0%,100% { opacity: 0.4; } 50% { opacity: 1; } }
29
34
  @keyframes taskPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(6,182,212,0.3); } 50% { box-shadow: 0 0 8px 2px rgba(6,182,212,0.2); } }
30
35
  .tp-flow-active { animation: flowDash 1.2s linear infinite; }
31
36
  .tp-node-active { animation: taskPulse 2s ease-in-out infinite; }
32
37
  .tp-node:hover { transform: scale(1.03); z-index: 10; }
33
- .tp-customer-badge { background: linear-gradient(135deg, #6366f1, #a855f7); color: #fff; font-size: 9px; padding: 1px 6px; border-radius: 8px; font-weight: 600; }
34
38
  .tp-chain-tag { font-size: 9px; padding: 1px 5px; border-radius: 4px; font-weight: 600; letter-spacing: 0.02em; }
35
39
  `;
36
40
  document.head.appendChild(style);
@@ -173,13 +177,13 @@ function formatDuration(ms) {
173
177
  function tag(color, text) { return h('span', { className: 'tp-chain-tag', style: { background: color + '22', color: color } }, text); }
174
178
 
175
179
  var toolbarBtnStyle = {
176
- background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.12)',
177
- borderRadius: 6, color: '#fff', fontSize: 12, fontWeight: 600, padding: '4px 10px', cursor: 'pointer',
180
+ background: 'var(--tp-border)', border: '1px solid rgba(255,255,255,0.12)',
181
+ borderRadius: 6, color: 'var(--tp-text)', fontSize: 12, fontWeight: 600, padding: '4px 10px', cursor: 'pointer',
178
182
  };
179
183
  function legendDot(color, label) {
180
184
  return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
181
185
  h('div', { style: { width: 8, height: 8, borderRadius: '50%', background: color } }),
182
- h('span', { style: { color: 'rgba(255,255,255,0.5)', fontSize: 11 } }, label)
186
+ h('span', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } }, label)
183
187
  );
184
188
  }
185
189
  var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
@@ -191,10 +195,10 @@ function CustomerBadge(props) {
191
195
  var c = props.customer;
192
196
  if (!c) return null;
193
197
  return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '4px 8px', background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 8, fontSize: 11, marginBottom: 4 } },
194
- h('div', { style: { width: 20, height: 20, borderRadius: '50%', background: 'linear-gradient(135deg, #6366f1, #a855f7)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 9, fontWeight: 700, flexShrink: 0 } }, (c.name || '?').charAt(0).toUpperCase()),
198
+ h('div', { style: { width: 20, height: 20, borderRadius: '50%', background: 'linear-gradient(135deg, #6366f1, #a855f7)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--tp-text)', fontSize: 9, fontWeight: 700, flexShrink: 0 } }, (c.name || '?').charAt(0).toUpperCase()),
195
199
  h('div', { style: { overflow: 'hidden' } },
196
- h('div', { style: { fontWeight: 600, color: '#fff', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, c.name || 'Unknown'),
197
- h('div', { style: { color: 'rgba(255,255,255,0.4)', fontSize: 9 } },
200
+ h('div', { style: { fontWeight: 600, color: 'var(--tp-text)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, c.name || 'Unknown'),
201
+ h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 9 } },
198
202
  c.isNew ? 'New customer' : (c.company || c.email || c.channel || '')
199
203
  )
200
204
  )
@@ -227,7 +231,7 @@ function TaskDetail(props) {
227
231
 
228
232
  // Customer context
229
233
  task.customerContext && h('div', { style: { padding: 12, background: 'rgba(99,102,241,0.06)', border: '1px solid rgba(99,102,241,0.15)', borderRadius: 'var(--radius)', marginBottom: 16 } },
230
- h('div', { style: { fontSize: 11, fontWeight: 600, color: 'rgba(255,255,255,0.5)', marginBottom: 8 } }, 'CUSTOMER'),
234
+ h('div', { style: { fontSize: 11, fontWeight: 600, color: 'var(--tp-text-dim)', marginBottom: 8 } }, 'CUSTOMER'),
231
235
  h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '6px 16px', fontSize: 13 } },
232
236
  task.customerContext.name && h(Fragment, null, h('div', { style: { color: 'var(--text-muted)', fontSize: 11 } }, 'Name'), h('div', null, task.customerContext.name)),
233
237
  task.customerContext.email && h(Fragment, null, h('div', { style: { color: 'var(--text-muted)', fontSize: 11 } }, 'Email'), h('div', null, task.customerContext.email)),
@@ -267,7 +271,7 @@ function TaskDetail(props) {
267
271
  return h(Fragment, { key: ct.id },
268
272
  i > 0 && h('div', { style: { display: 'flex', alignItems: 'center', flexShrink: 0 } },
269
273
  h('div', { style: { width: 32, height: 2, background: (DELEGATION_COLORS[ct.delegationType] || '#6366f1') + '66' } }),
270
- h('div', { style: { fontSize: 8, color: 'rgba(255,255,255,0.4)', position: 'relative', top: -8 } }, ct.delegationType || '')
274
+ h('div', { style: { fontSize: 8, color: 'var(--tp-text-dim)', position: 'relative', top: -8 } }, ct.delegationType || '')
271
275
  ),
272
276
  h('div', { style: {
273
277
  padding: '6px 10px', borderRadius: 8, fontSize: 11, flexShrink: 0,
@@ -312,32 +316,32 @@ function TaskDetail(props) {
312
316
  function MetricsBar(props) {
313
317
  var s = props.stats;
314
318
  function chip(label, value, color) {
315
- return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, padding: '3px 8px', background: 'rgba(255,255,255,0.04)', borderRadius: 6 } },
316
- h('span', { style: { fontSize: 10, color: 'rgba(255,255,255,0.35)' } }, label),
319
+ return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, padding: '3px 8px', background: 'var(--tp-card)', borderRadius: 6 } },
320
+ h('span', { style: { fontSize: 10, color: 'var(--tp-text-dim)' } }, label),
317
321
  h('span', { style: { fontSize: 11, fontWeight: 700, color: color } }, value)
318
322
  );
319
323
  }
320
324
  var hasActivity = s.total > 0;
321
325
 
322
- return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '6px 16px', borderBottom: '1px solid rgba(255,255,255,0.06)', background: 'rgba(0,0,0,0.12)', flexShrink: 0, overflowX: 'auto', fontSize: 11 } },
323
- h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.25)', fontWeight: 600, letterSpacing: '0.06em', marginRight: 2 } }, 'TODAY'),
326
+ return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '6px 16px', borderBottom: '1px solid var(--tp-border)', background: 'var(--tp-metrics)', flexShrink: 0, overflowX: 'auto', fontSize: 11 } },
327
+ h('span', { style: { fontSize: 9, color: 'var(--tp-text-faint)', fontWeight: 600, letterSpacing: '0.06em', marginRight: 2 } }, 'TODAY'),
324
328
  chip('Done', s.todayCompleted || 0, '#22c55e'),
325
329
  chip('Active', s.inProgress || 0, '#06b6d4'),
326
330
  chip('New', s.todayCreated || 0, '#f59e0b'),
327
331
  s.todayFailed > 0 && chip('Failed', s.todayFailed, '#ef4444'),
328
- hasActivity && h('div', { style: { width: 1, height: 14, background: 'rgba(255,255,255,0.08)' } }),
329
- hasActivity && h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.25)', fontWeight: 600, letterSpacing: '0.06em' } }, 'ALL'),
332
+ hasActivity && h('div', { style: { width: 1, height: 14, background: 'var(--tp-border)' } }),
333
+ hasActivity && h('span', { style: { fontSize: 9, color: 'var(--tp-text-faint)', fontWeight: 600, letterSpacing: '0.06em' } }, 'ALL'),
330
334
  hasActivity && chip('Total', s.total, 'rgba(255,255,255,0.6)'),
331
335
  s.avgDurationMs > 0 && chip('Avg', formatDuration(s.avgDurationMs), '#fff'),
332
336
  s.totalTokens > 0 && chip('Tokens', s.totalTokens > 999999 ? (s.totalTokens / 1000000).toFixed(1) + 'M' : s.totalTokens > 999 ? (s.totalTokens / 1000).toFixed(1) + 'K' : s.totalTokens, '#a855f7'),
333
337
  s.totalCost > 0 && chip('Cost', '$' + s.totalCost.toFixed(2), '#22c55e'),
334
338
  s.topAgents && s.topAgents.length > 0 && h(Fragment, null,
335
- h('div', { style: { width: 1, height: 14, background: 'rgba(255,255,255,0.08)' } }),
339
+ h('div', { style: { width: 1, height: 14, background: 'var(--tp-border)' } }),
336
340
  s.topAgents.slice(0, 3).map(function(a) {
337
- return h('div', { key: a.agent, style: { display: 'flex', alignItems: 'center', gap: 3, padding: '2px 6px', background: 'rgba(255,255,255,0.04)', borderRadius: 6 } },
341
+ return h('div', { key: a.agent, style: { display: 'flex', alignItems: 'center', gap: 3, padding: '2px 6px', background: 'var(--tp-card)', borderRadius: 6 } },
338
342
  h('div', { style: { width: 12, height: 12, borderRadius: '50%', background: '#6366f133', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 7, fontWeight: 700, color: '#6366f1' } }, (a.name || '?').charAt(0).toUpperCase()),
339
- h('span', { style: { fontSize: 10, color: '#fff', fontWeight: 600 } }, a.name),
340
- h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.3)' } }, a.completed + '/' + a.active)
343
+ h('span', { style: { fontSize: 10, color: 'var(--tp-text)', fontWeight: 600 } }, a.name),
344
+ h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)' } }, a.completed + '/' + a.active)
341
345
  );
342
346
  })
343
347
  )
@@ -528,8 +532,8 @@ export function TaskPipelinePage() {
528
532
  var hoveredNode = hoveredId ? nodes.find(function(n) { return n.id === hoveredId; }) : null;
529
533
 
530
534
  // ─── Toolbar ─────────────────────────────────────────
531
- var toolbar = h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px', borderBottom: '1px solid rgba(255,255,255,0.08)', background: 'rgba(0,0,0,0.3)', flexShrink: 0, flexWrap: 'wrap' } },
532
- h('div', { style: { fontWeight: 700, fontSize: 14, color: '#fff', display: 'flex', alignItems: 'center', gap: 6 } },
535
+ var toolbar = h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px', borderBottom: '1px solid var(--tp-border)', background: 'var(--tp-toolbar)', flexShrink: 0, flexWrap: 'wrap' } },
536
+ h('div', { style: { fontWeight: 700, fontSize: 14, color: 'var(--tp-text)', display: 'flex', alignItems: 'center', gap: 6 } },
533
537
  I.workflow(), 'Task Pipeline',
534
538
  h(HelpButton, { label: 'Task Pipeline' },
535
539
  h('p', null, 'Visual flow of all agent tasks. Tasks flow left-to-right showing delegation chains, multi-agent handoffs, and circular review loops.'),
@@ -554,9 +558,9 @@ export function TaskPipelinePage() {
554
558
  ),
555
559
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
556
560
  h('div', { style: { width: 8, height: 8, borderRadius: '50%', background: '#22c55e', animation: 'flowPulse 2s infinite' } }),
557
- h('span', { style: { color: 'rgba(255,255,255,0.4)', fontSize: 11 } }, 'Live')
561
+ h('span', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } }, 'Live')
558
562
  ),
559
- h('div', { style: { color: 'rgba(255,255,255,0.4)', fontSize: 11 } },
563
+ h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } },
560
564
  (stats.inProgress || 0) + ' active \u00B7 ' + (stats.completed || 0) + ' done \u00B7 ' + (stats.total || 0) + ' total'
561
565
  ),
562
566
  h('div', { style: { flex: 1 } }),
@@ -570,7 +574,7 @@ export function TaskPipelinePage() {
570
574
  legendDot(STATUS_COLORS.failed, 'Failed'),
571
575
  h('div', { style: { width: 1, height: 14, background: 'rgba(255,255,255,0.12)' } }),
572
576
  h('button', { onClick: function() { setZoom(function(z) { return Math.min(3, z + 0.2); }); }, style: toolbarBtnStyle }, '+'),
573
- h('div', { style: { color: 'rgba(255,255,255,0.5)', fontSize: 11, minWidth: 36, textAlign: 'center' } }, Math.round(zoom * 100) + '%'),
577
+ h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 11, minWidth: 36, textAlign: 'center' } }, Math.round(zoom * 100) + '%'),
574
578
  h('button', { onClick: function() { setZoom(function(z) { return Math.max(0.15, z - 0.2); }); }, style: toolbarBtnStyle }, '\u2212'),
575
579
  h('button', { onClick: fitToView, style: toolbarBtnStyle }, 'Fit'),
576
580
  h('button', { onClick: loadData, style: toolbarBtnStyle }, 'Refresh'),
@@ -578,13 +582,13 @@ export function TaskPipelinePage() {
578
582
 
579
583
  if (loading) return h('div', { style: { padding: 40, textAlign: 'center', color: 'var(--text-muted)' } }, 'Loading task pipeline...');
580
584
 
581
- if (nodes.length === 0) return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: BG, borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
585
+ if (nodes.length === 0) return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--tp-bg)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
582
586
  toolbar,
583
587
  h(MetricsBar, { stats: stats }),
584
588
  h('div', { style: { flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column' } },
585
589
  h('div', { style: { width: 48, height: 48, borderRadius: 12, background: 'rgba(99,102,241,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16, color: '#6366f1' } }, I.workflow()),
586
- h('div', { style: { fontSize: 16, fontWeight: 600, marginBottom: 6, color: '#fff' } }, 'No Tasks in Pipeline'),
587
- h('div', { style: { color: 'rgba(255,255,255,0.5)', fontSize: 13 } }, 'Tasks will appear here as agents are assigned work.')
590
+ h('div', { style: { fontSize: 16, fontWeight: 600, marginBottom: 6, color: 'var(--tp-text)' } }, 'No Tasks in Pipeline'),
591
+ h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 13 } }, 'Tasks will appear here as agents are assigned work.')
588
592
  )
589
593
  );
590
594
 
@@ -600,7 +604,7 @@ export function TaskPipelinePage() {
600
604
  }
601
605
  }
602
606
 
603
- return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: BG, borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
607
+ return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--tp-bg)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
604
608
  toolbar,
605
609
  // Metrics bar
606
610
  h(MetricsBar, { stats: stats }),
@@ -615,7 +619,7 @@ export function TaskPipelinePage() {
615
619
 
616
620
  // Chain labels (left side)
617
621
  chainInfos.map(function(ci, i) {
618
- return h('div', { key: ci.chainId, style: { position: 'absolute', left: 4, top: ci.y - 2, fontSize: 9, color: 'rgba(255,255,255,0.25)', fontFamily: 'var(--font-mono)', letterSpacing: '0.04em', maxWidth: PAD - 8, overflow: 'hidden' } },
622
+ return h('div', { key: ci.chainId, style: { position: 'absolute', left: 4, top: ci.y - 2, fontSize: 9, color: 'var(--tp-text-faint)', fontFamily: 'var(--font-mono)', letterSpacing: '0.04em', maxWidth: PAD - 8, overflow: 'hidden' } },
619
623
  ci.customer && h(CustomerBadge, { customer: ci.customer })
620
624
  );
621
625
  }),
@@ -704,17 +708,17 @@ export function TaskPipelinePage() {
704
708
  h('div', { style: { width: 18, height: 18, borderRadius: '50%', background: sc + '33', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 8, fontWeight: 700, color: sc, flexShrink: 0, border: '1px solid ' + sc + '44' } },
705
709
  (t.assignedToName || t.assignedTo || '?').charAt(0).toUpperCase()
706
710
  ),
707
- h('span', { style: { fontSize: 11, fontWeight: 600, color: '#fff', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, t.title)
711
+ h('span', { style: { fontSize: 11, fontWeight: 600, color: 'var(--tp-text)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, t.title)
708
712
  ),
709
713
  // Status + agent name + time
710
714
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' } },
711
715
  tag(sc, t.status.replace('_', ' ')),
712
- h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.4)' } }, t.assignedToName || t.assignedTo),
716
+ h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)' } }, t.assignedToName || t.assignedTo),
713
717
  t.delegationType && tag(DELEGATION_COLORS[t.delegationType] || '#6b7394', t.delegationType),
714
- h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.3)', marginLeft: 'auto' } }, timeAgo(t.createdAt))
718
+ h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)', marginLeft: 'auto' } }, timeAgo(t.createdAt))
715
719
  ),
716
720
  // Progress bar
717
- isActive && t.progress > 0 && h('div', { style: { height: 2, background: 'rgba(255,255,255,0.08)', borderRadius: 1, overflow: 'hidden', marginTop: 1 } },
721
+ isActive && t.progress > 0 && h('div', { style: { height: 2, background: 'var(--tp-border)', borderRadius: 1, overflow: 'hidden', marginTop: 1 } },
718
722
  h('div', { style: { height: '100%', width: t.progress + '%', background: sc, borderRadius: 1, transition: 'width 0.3s' } })
719
723
  )
720
724
  );
@@ -751,15 +755,19 @@ export function TaskPipelinePage() {
751
755
 
752
756
  var totalW = steps.length * STEP_W + (steps.length - 1) * STEP_GAP;
753
757
 
754
- return h('div', { style: { position: 'absolute', left: flowX, top: flowY, pointerEvents: 'auto' } },
758
+ var maxFlowW = Math.max(totalW + 40, 400);
759
+ var containerW = (containerRef.current ? containerRef.current.getBoundingClientRect().width / zoom : 800) - flowX;
760
+ if (maxFlowW > containerW) maxFlowW = Math.max(containerW, 320);
761
+
762
+ return h('div', { style: { position: 'absolute', left: flowX, top: flowY, pointerEvents: 'auto', maxWidth: maxFlowW, zIndex: 20 } },
755
763
  // Background card
756
- h('div', { style: { background: 'rgba(10,12,20,0.85)', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 12, padding: '14px 16px 12px', backdropFilter: 'blur(8px)' } },
764
+ h('div', { style: { background: 'var(--bg-primary, rgba(10,12,20,0.95))', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 12, padding: '14px 16px 12px', backdropFilter: 'blur(8px)', overflowX: 'auto', overflowY: 'hidden' } },
757
765
  // Header
758
766
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 } },
759
- h('span', { style: { fontSize: 10, fontWeight: 600, color: 'rgba(255,255,255,0.4)', letterSpacing: '0.06em' } }, 'TASK FLOW'),
767
+ h('span', { style: { fontSize: 10, fontWeight: 600, color: 'var(--tp-text-dim)', letterSpacing: '0.06em' } }, 'TASK FLOW'),
760
768
  expandedChain[0].chainId && h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.2)', fontFamily: 'var(--font-mono)' } }, '#' + expandedChain[0].chainId.slice(0, 8)),
761
769
  h('div', { style: { flex: 1 } }),
762
- h('button', { className: 'tp-node', onClick: function() { setExpandedTaskId(null); }, style: { background: 'none', border: 'none', color: 'rgba(255,255,255,0.3)', cursor: 'pointer', fontSize: 14, padding: '0 2px' } }, '\u00D7')
770
+ h('button', { className: 'tp-node', onClick: function() { setExpandedTaskId(null); }, style: { background: 'none', border: 'none', color: 'var(--tp-text-dim)', cursor: 'pointer', fontSize: 14, padding: '0 2px' } }, '\u00D7')
763
771
  ),
764
772
  // Flow
765
773
  h('div', { style: { position: 'relative', height: STEP_H + 8, minWidth: totalW } },
@@ -823,7 +831,7 @@ export function TaskPipelinePage() {
823
831
  // Info
824
832
  h('div', { style: { overflow: 'hidden', flex: 1, minWidth: 0 } },
825
833
  h('div', { style: { fontSize: 11, fontWeight: 600, color: isTerminal ? sc : '#fff', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, step.label),
826
- !isTerminal && h('div', { style: { fontSize: 9, color: 'rgba(255,255,255,0.35)', marginTop: 1 } },
834
+ !isTerminal && h('div', { style: { fontSize: 9, color: 'var(--tp-text-dim)', marginTop: 1 } },
827
835
  step.type === 'person' || step.isHuman ? 'Human' : step.type === 'system' ? 'System' : 'Agent',
828
836
  step.duration ? ' \u00B7 ' + formatDuration(step.duration) : '',
829
837
  step.status === 'in_progress' && step.progress > 0 ? ' \u00B7 ' + step.progress + '%' : ''
@@ -846,13 +854,13 @@ export function TaskPipelinePage() {
846
854
  padding: '10px 14px', pointerEvents: 'none', zIndex: 1000, minWidth: 180, maxWidth: 280,
847
855
  }},
848
856
  hoveredNode.task.customerContext && h(CustomerBadge, { customer: hoveredNode.task.customerContext }),
849
- h('div', { style: { fontSize: 12, fontWeight: 600, color: '#fff', marginBottom: 6 } }, hoveredNode.task.title),
857
+ h('div', { style: { fontSize: 12, fontWeight: 600, color: 'var(--tp-text)', marginBottom: 6 } }, hoveredNode.task.title),
850
858
  h('div', { style: { display: 'flex', flexDirection: 'column', gap: 3, fontSize: 11 } },
851
- h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'rgba(255,255,255,0.4)' } }, 'Agent'), h('span', { style: { fontWeight: 600 } }, hoveredNode.task.assignedToName || '-')),
852
- h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'rgba(255,255,255,0.4)' } }, 'Status'), h('span', { style: { color: STATUS_COLORS[hoveredNode.task.status] } }, hoveredNode.task.status.replace('_', ' '))),
853
- hoveredNode.task.chainId && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'rgba(255,255,255,0.4)' } }, 'Chain Step'), h('span', null, '#' + ((hoveredNode.task.chainSeq || 0) + 1))),
854
- hoveredNode.task.delegationType && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'rgba(255,255,255,0.4)' } }, 'Type'), h('span', { style: { color: DELEGATION_COLORS[hoveredNode.task.delegationType] } }, hoveredNode.task.delegationType)),
855
- hoveredNode.task.progress > 0 && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'rgba(255,255,255,0.4)' } }, 'Progress'), h('span', { style: { color: STATUS_COLORS.in_progress } }, hoveredNode.task.progress + '%'))
859
+ h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Agent'), h('span', { style: { fontWeight: 600 } }, hoveredNode.task.assignedToName || '-')),
860
+ h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Status'), h('span', { style: { color: STATUS_COLORS[hoveredNode.task.status] } }, hoveredNode.task.status.replace('_', ' '))),
861
+ hoveredNode.task.chainId && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Chain Step'), h('span', null, '#' + ((hoveredNode.task.chainSeq || 0) + 1))),
862
+ hoveredNode.task.delegationType && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Type'), h('span', { style: { color: DELEGATION_COLORS[hoveredNode.task.delegationType] } }, hoveredNode.task.delegationType)),
863
+ hoveredNode.task.progress > 0 && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Progress'), h('span', { style: { color: STATUS_COLORS.in_progress } }, hoveredNode.task.progress + '%'))
856
864
  )
857
865
  ),
858
866
 
@@ -28,9 +28,9 @@ export function createTaskQueueRoutes(taskQueue: TaskQueueManager) {
28
28
  });
29
29
 
30
30
  // GET /task-pipeline/stats — pipeline statistics
31
- router.get('/stats', (c) => {
31
+ router.get('/stats', async (c) => {
32
32
  const orgId = c.req.query('orgId') || '';
33
- const stats = taskQueue.getPipelineStats(orgId);
33
+ const stats = await taskQueue.getPipelineStats(orgId);
34
34
  return c.json(stats);
35
35
  });
36
36
 
@@ -385,11 +385,11 @@ export class TaskQueueManager {
385
385
  return this.getAllTasks(orgId, limit);
386
386
  }
387
387
 
388
- getPipelineStats(orgId?: string): {
388
+ async getPipelineStats(orgId?: string): Promise<{
389
389
  created: number; assigned: number; inProgress: number; completed: number; failed: number; cancelled: number; total: number;
390
390
  todayCompleted: number; todayFailed: number; todayCreated: number; avgDurationMs: number; totalCost: number; totalTokens: number;
391
391
  topAgents: Array<{ agent: string; name: string; completed: number; active: number }>;
392
- } {
392
+ }> {
393
393
  const stats = {
394
394
  created: 0, assigned: 0, inProgress: 0, completed: 0, failed: 0, cancelled: 0, total: 0,
395
395
  todayCompleted: 0, todayFailed: 0, todayCreated: 0, avgDurationMs: 0, totalCost: 0, totalTokens: 0,
@@ -434,6 +434,34 @@ export class TaskQueueManager {
434
434
  .map(([agent, d]) => ({ agent, ...d }))
435
435
  .sort((a, b) => (b.completed + b.active) - (a.completed + a.active))
436
436
  .slice(0, 5);
437
+
438
+ // If DB available, also query today's stats from DB to catch anything not in memory
439
+ if (this.db) {
440
+ try {
441
+ const todayISO = todayStart.toISOString();
442
+ const dbToday = await this.db.get(
443
+ `SELECT COUNT(*) FILTER (WHERE status='completed' AND completed_at >= ?) as dc,
444
+ COUNT(*) FILTER (WHERE status='failed' AND completed_at >= ?) as df,
445
+ COUNT(*) FILTER (WHERE created_at >= ?) as dn
446
+ FROM task_pipeline` + (orgId ? ` WHERE org_id = ?` : ''),
447
+ orgId ? [todayISO, todayISO, todayISO, orgId] : [todayISO, todayISO, todayISO]
448
+ ).catch(() => null);
449
+ // Postgres FILTER may not work on all DBs, fallback to separate counts
450
+ if (!dbToday || dbToday.dc === undefined) {
451
+ const r1 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE status='completed' AND completed_at >= ?`, [todayISO]).catch(() => null);
452
+ const r2 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE status='failed' AND completed_at >= ?`, [todayISO]).catch(() => null);
453
+ const r3 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE created_at >= ?`, [todayISO]).catch(() => null);
454
+ if (r1?.c > stats.todayCompleted) stats.todayCompleted = r1.c;
455
+ if (r2?.c > stats.todayFailed) stats.todayFailed = r2.c;
456
+ if (r3?.c > stats.todayCreated) stats.todayCreated = r3.c;
457
+ } else {
458
+ if (dbToday.dc > stats.todayCompleted) stats.todayCompleted = dbToday.dc;
459
+ if (dbToday.df > stats.todayFailed) stats.todayFailed = dbToday.df;
460
+ if (dbToday.dn > stats.todayCreated) stats.todayCreated = dbToday.dn;
461
+ }
462
+ } catch { /* ignore — in-memory stats are fine */ }
463
+ }
464
+
437
465
  return stats;
438
466
  }
439
467