// Kayser v2 — High-leverage MVP additions // Morning brief card · Audit log sheet · Push notification preview · // Hold-for-review mode · Real Pause toggle · Offline banner // ============ MORNING BRIEF ============ // A special "recap" card type that surfaces at the top of the day. // Appears once per day in the chat thread when Kayser has activity to summarize. function KxV2MorningBrief({ brief, onOpenItem }) { if (!brief) return null; return (
{/* Eyebrow */}
✦ Morning brief · {brief.date} {brief.t}
{/* Greeting */}
{brief.greeting}
{brief.summary}
{/* Counters */}
{[ { k: 'NEEDS YOU', v: brief.needs, c: KX2.brand }, { k: 'AUTO-HANDLED', v: brief.handled, c: KX2.approve }, { k: 'WATCHING', v: brief.watching, c: KX2.warn }, ].map(s => (
{s.k}
{s.v}
))}
{/* Top priorities */} {brief.priorities && brief.priorities.length > 0 && (
{brief.priorities.map((p, i) => ( ))}
)} {brief.cta && ( )}
); } const KXV2_MORNING_BRIEF = { date: 'Tue Apr 28', t: '7:42 AM', greeting: 'Morning, Wes.', summary: "While you slept I caught up on yesterday. Two things need you this morning; the rest is in hand.", needs: 2, handled: 4, watching: 7, priorities: [ { kind: 'needs', text: 'Send reminder to Garcia · #1031 · $4,800 · 7d overdue' }, { kind: 'needs', text: 'Confirm Williams porch estimate · today 1 PM' }, { kind: 'watching', text: '3 invoices crossed 60-day line · $11.2K outstanding' }, ], cta: 'See the day', }; // ============ AUDIT LOG SHEET ============ // "What did Kayser do for me this week?" — every auto-handled action, filterable. const KXV2_AUDIT = [ { t: 'Today 7:42 AM', kind: 'reschedule', who: 'Patel · exterior repaint', what: 'Moved from Wed 2 PM to Thu 9 AM', why: 'Weather rule · 70% rain forecast', can_undo: true }, { t: 'Today 6:58 AM', kind: 'reply', who: 'New lead · Reyes Bakery', what: 'Sent intro reply with availability', why: 'Auto-reply rule · responds within 4 hrs', can_undo: true }, { t: 'Today 6:18 AM', kind: 'log', who: 'Sherwin Williams receipt', what: 'Filed to job 1822 expenses', why: 'Pattern match · vendor + amount + date', can_undo: true }, { t: 'Yesterday 4:21 PM', kind: 'reminder', who: 'Chen kitchen', what: 'Sent appointment reminder', why: 'Same-day reminder rule', can_undo: false }, { t: 'Yesterday 11:02 AM', kind: 'log', who: 'Home Depot receipt', what: 'Filed to job 1827 expenses', why: 'Pattern match · matched job by date', can_undo: false }, { t: 'Yesterday 9:14 AM', kind: 'reply', who: 'Jenkins inquiry', what: 'Replied: not taking new clients until June', why: 'Capacity rule · you set this on Apr 12', can_undo: false }, { t: 'Apr 26 3:18 PM', kind: 'reminder', who: 'Garcia · #1031', what: 'Soft nudge at day 5', why: 'Reminder rule · invoice >5 days', can_undo: false }, { t: 'Apr 26 8:00 AM', kind: 'brief', who: 'You', what: 'Sent morning brief', why: 'Daily brief on', can_undo: false }, ]; const KXV2_AUDIT_ICONS = { reschedule: '◷', reply: '↗', log: '◈', reminder: '◌', brief: '✦', }; function KxV2AuditSheet({ open, onClose }) { const [filter, setFilter] = React.useState('all'); const groups = ['all', 'reply', 'reminder', 'reschedule', 'log']; const filtered = filter === 'all' ? KXV2_AUDIT : KXV2_AUDIT.filter(a => a.kind === filter); return (
Every action I took on my own. Tap any to see why — and undo it if recent.
{groups.map(g => ( ))}
{filtered.map((a, i) => (
{KXV2_AUDIT_ICONS[a.kind] || '·'}
{a.who} {a.t}
{a.what}
{a.why} {a.can_undo && ( )}
))}
); } // ============ PUSH NOTIFICATION PREVIEW ============ // A small floating banner that mimics a system push, slides in from top. // Used to demo the proactive feel without real APNs/FCM. function KxV2PushBanner({ note, onDismiss, onTap }) { React.useEffect(() => { if (!note) return; const t = setTimeout(onDismiss, 6000); return () => clearTimeout(t); }, [note, onDismiss]); if (!note) return null; return (
K
{note.title || 'Kayser'}
{note.body}
); } // ============ OFFLINE BANNER ============ function KxV2OfflineBanner({ visible }) { if (!visible) return null; return (
You're offline — I'll catch up when you're back.
); } // ============ HOLD-FOR-REVIEW MODE OPTION ON APPROVAL CARDS ============ // Reusable button that schedules a draft for delayed send (asymmetric undo). function KxV2HoldForReview({ defaultMinutes = 120, onSchedule }) { const [minutes, setMinutes] = React.useState(defaultMinutes); const options = [ { v: 30, label: '30 min' }, { v: 120, label: '2 hr' }, { v: 480, label: 'Tonight' }, { v: 1440, label: 'Tomorrow' }, ]; return (
HOLD FOR REVIEW · CANCELABLE
I'll wait before sending. You can review, edit, or cancel anytime in that window.
{options.map(o => ( ))}
); } Object.assign(window, { KxV2MorningBrief, KXV2_MORNING_BRIEF, KxV2AuditSheet, KXV2_AUDIT, KxV2PushBanner, KxV2OfflineBanner, KxV2HoldForReview, });