Files
aiturk-hermes-ide/apps/chrome/extension/background.js
T
yilsemandClaude Opus 5.5 86a6621936
Server CI and Windows package / verify (push) Successful in 3m33s
Server CI and Windows package / windows-package (push) Successful in 7m36s
feat(chrome): let the IDE agent use the user's Chrome and beta.42
The AITURK Chrome extension now registers the user's Chrome as the desktop
backend's browser controller, the way the ChatGPT extension lets its agent
work in the user's browser. The agent's existing browser tools (navigate,
snapshot, click, type, scroll, back, press, get_images, vision) run in its
own background tabs grouped as "AITURK", or a tab the user hands over.

Backend: a local desktop lane in the browser-control broker. One controller
registered from the loopback desktop transport is offered to every desktop
session as a lane template; each session still gets its own exact scope on
first use. The lane has its own switch (browser.extension_control.local_desktop,
on by default); with no extension registered, or after it disconnects, the
normal browser backend runs unchanged. browser_vision turns the extension's
capture into the usual native/auxiliary vision result.

Bridge: forwards controller commands only to a connection that registered,
refuses unknown or oversized commands, relays results.

Extension: service-worker controller with its own native connection,
trusted chrome.debugger input (press/release only: a hover move waits 5 s on
background tabs), refusal of password and payment-card fields and of
browser, extension, file and Web Store pages, panel switch, Stop, tab
hand-over, recent actions, Alt+Shift+A and right-click "send to AITURK".
Cancelling Chrome's debugging bar stops the agent. Existing panel flows and
privacy rules are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:38:52 +03:00

43 lines
2.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createController } from './controller.js'
const controller = createController({ chrome })
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }).catch(() => {})
// The side panel talks to the controller; nothing else may.
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
const type = String(message?.type || '')
if (sender.id !== chrome.runtime.id || !type.startsWith('control.') || type === 'control.state') return false
controller.onMessage(message, sender).then(sendResponse, error => sendResponse({ failure: String(error?.message || error) }))
return true
})
chrome.debugger.onDetach.addListener((source, reason) => controller.onDebuggerDetach(source, reason))
chrome.tabs.onRemoved.addListener(tabId => { void controller.onTabRemoved(tabId) })
chrome.alarms.onAlarm.addListener(alarm => controller.onAlarm(alarm.name))
const MENU = [
{ id: 'aiturk-selection', title: 'AITURK’e gönder: seçili metin', contexts: ['selection'] },
{ id: 'aiturk-page', title: 'AITURK’e gönder: bu sayfa', contexts: ['page'] },
{ id: 'aiturk-share', title: 'Bu sekmeyi AITURK ajanına ver', contexts: ['page'] },
]
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.removeAll(() => { for (const item of MENU) chrome.contextMenus.create(item) })
})
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (!tab?.windowId) return
// Opening the panel must happen inside the click's user gesture, before any await.
chrome.sidePanel.open({ windowId: tab.windowId }).catch(() => {})
if (info.menuItemId === 'aiturk-share') {
void chrome.storage.local.get('selectedSession')
.then(saved => controller.shareTab(tab, typeof saved.selectedSession === 'string' ? saved.selectedSession : null))
.catch(error => chrome.storage.session.set({ pendingNotice: String(error?.message || error) }))
return
}
void chrome.storage.session.set({ pendingContext: {
kind: info.menuItemId === 'aiturk-selection' ? 'selection' : 'page', tabId: tab.id,
text: info.selectionText ? info.selectionText.slice(0, 24000) : '', at: Date.now(),
} })
})
void controller.connect()