Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/chrome-extension/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@
}
});

// Auto-dismiss beforeunload dialogs so agent navigation isn't blocked.
// Regular dialogs (alert/confirm/prompt) are left for the agent to handle
// via handle_dialog, but a notification event is sent.
chrome.debugger.onEvent.addListener((source, method, params) => {
if (method !== 'Page.javascriptDialogOpening' || !source.tabId) return;
const p = params as { type?: string; message?: string; url?: string };

if (p.type === 'beforeunload') {
chrome.debugger.sendCommand(source, 'Page.handleJavaScriptDialog', { accept: true })
.catch(() => { /* tab may have closed */ });
console.log(`[Markus] Auto-dismissed beforeunload dialog on tab ${source.tabId}`);

Check warning on line 52 in packages/chrome-extension/src/background.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected console statement. Only these console methods are allowed: warn, error
return;
}

const pageId = pm.peekPageId(source.tabId);
client.send({
event: 'dialog_opened',
data: { tabId: source.tabId, pageId, type: p.type, message: p.message },
});
});

// Handle popup status queries
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
if (msg.type === 'getStatus') {
Expand All @@ -55,8 +76,8 @@
// then connect to bridge.
pm.restore().then((restored) => {
if (restored) {
console.log('[Markus] Reconnecting with restored page state');

Check warning on line 79 in packages/chrome-extension/src/background.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected console statement. Only these console methods are allowed: warn, error
}
client.connect();
console.log('[Markus] Browser automation extension initialized');

Check warning on line 82 in packages/chrome-extension/src/background.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected console statement. Only these console methods are allowed: warn, error
});
65 changes: 27 additions & 38 deletions packages/web-ui/src/components/ChatTeamSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -887,46 +887,18 @@ export function ChatTeamSidebar({
return (
<>
<div className={`bg-surface-secondary rounded-xl my-1 flex flex-col ${width != null ? 'shrink-0' : 'flex-1 min-w-0'}`} style={hidden ? { display: 'none' } : width != null ? { width } : undefined}>
{/* Header with title + pause toggle */}
{/* Header with title + manage button */}
<div className="px-4 h-14 flex items-center shrink-0 gap-2">
{isMobile && <MobileMenuButton />}
<h2 className="text-lg font-semibold">{t('chat.title')}</h2>
<div className="ml-auto">
{globalPaused === null ? (
<span className="flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md border border-border-default text-fg-tertiary opacity-60">
<svg className="w-3 h-3 animate-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10" strokeDasharray="31.4 31.4" strokeLinecap="round" /></svg>
{t('common:status.loading', { defaultValue: '...' })}
</span>
) : (
<button
onClick={handlePauseClick}
disabled={pauseLoading}
title={globalPaused ? t('modals.resumeAll.title') : t('modals.pauseAll.title')}
className={`flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md border transition-colors ${
globalPaused
? 'bg-green-500/10 border-green-500/30 text-green-500 hover:bg-green-500/20'
: 'bg-amber-500/10 border-amber-500/30 text-amber-600 hover:bg-amber-500/20'
} disabled:opacity-50`}
>
{globalPaused ? (
<><svg className="w-3 h-3" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3" /></svg> {t('chat.resume')}</>
) : (
<><svg className="w-3 h-3" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16" /><rect x="14" y="4" width="4" height="16" /></svg> {t('chat.pause')}</>
)}
</button>
)}
</div>
</div>
{/* Action bar */}
{isAdmin && (
<div className="px-3 pt-2 pb-1 flex items-center gap-1.5" ref={actionMenuRef}>
<div className="relative flex-1">
{isAdmin && (
<div className="ml-auto relative" ref={actionMenuRef}>
<button
onClick={() => setActionMenu(!actionMenu)}
className="w-full flex items-center justify-center gap-1 px-2 py-1.5 text-[10px] font-medium text-fg-secondary hover:text-fg-primary bg-surface-elevated/60 hover:bg-surface-elevated rounded-lg transition-colors"
className="flex items-center gap-1 px-2.5 py-1 text-xs font-medium text-fg-secondary hover:text-fg-primary bg-surface-elevated/60 hover:bg-surface-elevated rounded-md transition-colors"
>
<span className="text-brand-500">+</span> {t('chat.manage')}
<svg className={`w-2.5 h-2.5 ml-auto transition-transform ${actionMenu ? 'rotate-180' : ''}`} fill="currentColor" viewBox="0 0 20 20">
<svg className={`w-2.5 h-2.5 transition-transform ${actionMenu ? 'rotate-180' : ''}`} fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clipRule="evenodd" />
</svg>
</button>
Expand All @@ -936,10 +908,9 @@ export function ChatTeamSidebar({
const rect = el.getBoundingClientRect();
const vw = window.innerWidth;
const pad = 8;
if (rect.right > vw - pad) el.style.left = 'auto';
if (rect.right > vw - pad) el.style.right = '0';
if (rect.right > vw - pad) { el.style.left = 'auto'; el.style.right = '0'; }
if (rect.left < pad) { el.style.left = '0'; el.style.right = 'auto'; }
}} className="absolute left-0 top-full mt-1 w-48 max-w-[calc(100vw-1rem)] bg-surface-secondary border border-border-default rounded-lg shadow-xl z-30 overflow-hidden">
}} className="absolute right-0 top-full mt-1 w-48 max-w-[calc(100vw-1rem)] bg-surface-secondary border border-border-default rounded-lg shadow-xl z-30 overflow-hidden">
<button onClick={() => { setActionMenu(false); setShowMethodChoice('agent'); }}
className="w-full text-left px-4 py-2.5 text-xs text-fg-secondary hover:bg-surface-elevated transition-colors">
<div className="font-medium flex items-center gap-1.5">
Expand Down Expand Up @@ -972,11 +943,29 @@ export function ChatTeamSidebar({
</div>
<div className="text-[10px] text-fg-tertiary mt-0.5 pl-[18px]">{t('chat.newGroupChatDesc')}</div>
</button>
{globalPaused !== null && (
<button
onClick={() => { setActionMenu(false); handlePauseClick(); }}
disabled={pauseLoading}
className={`w-full text-left px-4 py-2.5 text-xs hover:bg-surface-elevated border-t border-border-default transition-colors disabled:opacity-50 ${
globalPaused ? 'text-green-600' : 'text-amber-600'
}`}
>
<div className="font-medium flex items-center gap-1.5">
{globalPaused ? (
<><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3" /></svg> {t('chat.resume')}</>
) : (
<><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16" /><rect x="14" y="4" width="4" height="16" /></svg> {t('chat.pause')}</>
)}
</div>
<div className="text-[10px] text-fg-tertiary mt-0.5 pl-[18px]">{globalPaused ? t('modals.resumeAll.title') : t('modals.pauseAll.title')}</div>
</button>
)}
</div>
)}
</div>
</div>
)}
)}
</div>

{/* Sidebar content */}
<div className="flex-1 overflow-y-auto px-3 py-2 flex flex-col">
Expand Down
1 change: 1 addition & 0 deletions packages/web-ui/src/components/NotificationBell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ export function NotificationBell({ collapsed, userId, embeddedMode, onClose, sid
invalidateApiCache('/approvals');
invalidateApiCache('/notifications');
invalidateApiCache('/tasks');
invalidateApiCache('/taskboard');
invalidateApiCache('/requirements');
window.dispatchEvent(new CustomEvent('markus:data-changed'));
setTimeout(() => fetchData(), 800);
Expand Down
4 changes: 4 additions & 0 deletions packages/web-ui/src/locales/en/agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@
"since": "since {{time}}",
"refresh": "↻ Refresh",
"queue": "Queue ({{count}})",
"expandQueue": "Show {{count}} more…",
"collapseQueue": "Collapse",
"staleProcessingWarning": "Stale processing items detected (agent is idle)",
"agentDetails": "Agent Details",
"triageDecision": "Triage Decision",
"processingItem": "Processing: {{id}}…",
"deferred": "Deferred: {{count}}",
Expand Down
4 changes: 4 additions & 0 deletions packages/web-ui/src/locales/zh-CN/agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@
"since": "自 {{time}} 起",
"refresh": "↻ 刷新",
"queue": "队列({{count}})",
"expandQueue": "展开剩余 {{count}} 项…",
"collapseQueue": "收起",
"staleProcessingWarning": "存在异常处理中项目(Agent 已空闲)",
"agentDetails": "Agent 详情",
"triageDecision": "分拣决策",
"processingItem": "处理中:{{id}}…",
"deferred": "已推迟:{{count}}",
Expand Down
6 changes: 3 additions & 3 deletions packages/web-ui/src/pages/AgentBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -577,13 +577,13 @@ export function AgentBuilder({ authUser }: { authUser?: AuthUser } = {}) {
)}
{sharePrompt && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm" onClick={() => setSharePrompt(null)}>
<div className="bg-gray-900 border border-gray-700 rounded-xl max-w-sm w-full mx-4 p-6" onClick={e => e.stopPropagation()}>
<div className="bg-surface-secondary border border-border-default rounded-xl max-w-sm w-full mx-4 p-6 shadow-2xl" onClick={e => e.stopPropagation()}>
<h3 className="text-base font-semibold text-fg-primary mb-2">{t('common:share')}</h3>
<p className="text-sm text-fg-secondary mb-5">{t('share.imagePrompt')}</p>
<div className="flex gap-3">
<button
onClick={() => { const art = sharePrompt; setSharePrompt(null); PAYMENTS_ENABLED ? setShareModeTarget(art) : void handleShare(art); }}
className="flex-1 text-sm px-4 py-2 rounded-lg border border-border-default text-fg-secondary hover:text-fg-primary hover:border-gray-600 transition-colors">
className="flex-1 text-sm px-4 py-2 rounded-lg border border-border-default text-fg-secondary hover:text-fg-primary hover:border-fg-tertiary transition-colors">
{t('share.directly')}
</button>
<button
Expand All @@ -597,7 +597,7 @@ export function AgentBuilder({ authUser }: { authUser?: AuthUser } = {}) {
)}
{shareModeTarget && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm" onClick={() => setShareModeTarget(null)}>
<div className="bg-gray-900 border border-gray-700 rounded-xl max-w-sm w-full mx-4 p-6" onClick={e => e.stopPropagation()}>
<div className="bg-surface-secondary border border-border-default rounded-xl max-w-sm w-full mx-4 p-6 shadow-2xl" onClick={e => e.stopPropagation()}>
<ShareModeSelect
isUpdate={sharedMap.has(`${shareModeTarget.type}/${shareModeTarget.name}`)}
onCancel={() => setShareModeTarget(null)}
Expand Down
Loading
Loading