diff --git a/src/background/index.ts b/src/background/index.ts index bb53e8c..e23fb76 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -183,6 +183,10 @@ async function executeForBroker(callId: string, name: string, input: Record { if (targetTabId === null) { sendToPanel({ type: 'target_tab', tabId: null }); @@ -223,6 +227,13 @@ async function notifyTargetTab(): Promise { try { const tab = await chrome.tabs.get(targetTabId); sendToPanel({ type: 'target_tab', tabId: targetTabId, title: tab.title, url: tab.url }); + // Glow auf den neuen Arbeits-Tab übertragen (falls Agent gerade läuft) + notifyGlow(true); + // Tab in den Vordergrund bringen wenn focusWorkingTab aktiv + const cfg = await loadConfig(); + if (cfg.focusWorkingTab) { + await chrome.tabs.update(targetTabId, { active: true }).catch(() => {}); + } } catch { sendToPanel({ type: 'target_tab', tabId: null }); } @@ -724,7 +735,10 @@ function notifyCursor(tabId: number, x: number, y: number, click?: 'left' | 'rig async function notifyGlow(on: boolean): Promise { const cfg = await loadConfig(); if (cfg.pageOverlay !== 'glow' && cfg.pageOverlay !== 'both') return; - const id = await currentTabId().catch(() => undefined); + + // Glow an den Arbeits-Tab schicken, nicht an den aktiven Tab des Nutzers. + // targetTabId ist null wenn noch kein Tool gelaufen ist — dann aktiven Tab nehmen. + const id = targetTabId ?? await currentTabId().catch(() => undefined); if (typeof id !== 'number') return; chrome.tabs.sendMessage(id, { type: 'NEXUS_GLOW', on }).catch(() => {}); } diff --git a/src/shared/config.ts b/src/shared/config.ts index 0faabfe..a2b36c7 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -159,6 +159,13 @@ export interface ExtensionConfig { * zurückholen. Dieser Riegel greift unabhängig vom Risikomodus. */ blockMailSend: boolean; + + /** + * Arbeits-Tab in den Vordergrund bringen wenn der Agent ihn wechselt. + * false (Standard) = Agent arbeitet im Hintergrund, Nutzer kann anderen Tab nutzen. + * true = Tab wird bei jedem Wechsel sichtbar — gut zum Live-Zuschauen. + */ + focusWorkingTab: boolean; } export const DEFAULT_SYSTEM_PROMPT = `Du steuerst einen echten Browser wie ein Mensch: mit Mauszeiger und Tastatur. @@ -328,6 +335,7 @@ export const DEFAULT_CONFIG: ExtensionConfig = { memoryToken: '', memoryEnabled: false, blockMailSend: true, + focusWorkingTab: false, }; const STORAGE_KEY = 'nexus_ext_config'; diff --git a/src/sidepanel/app.ts b/src/sidepanel/app.ts index 413d1bc..0d8ce2e 100644 --- a/src/sidepanel/app.ts +++ b/src/sidepanel/app.ts @@ -88,6 +88,7 @@ const paceMsInput = need('paceMs'); const showCursorInput = need('showCursor'); const pageOverlaySelect = need('pageOverlay'); const blockMailSendInput = need('blockMailSend'); +const focusWorkingTabInput = need('focusWorkingTab'); const providerSelect = need('provider'); const baseUrlInput = need('baseUrl'); const apiKeyInput = need('apiKey'); @@ -379,6 +380,7 @@ function applyConfigToFields(cfg: ExtensionConfig): void { setFieldValue(paceMsInput, String(cfg.paceMs)); if (document.activeElement !== showCursorInput) showCursorInput.checked = cfg.showCursor; if (document.activeElement !== blockMailSendInput) blockMailSendInput.checked = cfg.blockMailSend; + if (document.activeElement !== focusWorkingTabInput) focusWorkingTabInput.checked = cfg.focusWorkingTab ?? false; setFieldValue(providerSelect, cfg.provider); setFieldValue(baseUrlInput, cfg.baseUrl); @@ -685,6 +687,10 @@ function wireSettings(): void { patchConfigValue({ showCursor: showCursorInput.checked }); }); + focusWorkingTabInput.addEventListener('change', () => { + patchConfigValue({ focusWorkingTab: focusWorkingTabInput.checked }); + }); + blockMailSendInput.addEventListener('change', () => { patchConfigValue({ blockMailSend: blockMailSendInput.checked }); if (!blockMailSendInput.checked) { diff --git a/src/sidepanel/index.html b/src/sidepanel/index.html index 17f70d6..7b6238c 100644 --- a/src/sidepanel/index.html +++ b/src/sidepanel/index.html @@ -1099,6 +1099,10 @@ +
+ + +