Communitygithub.com

fourth3950/ego-lite

Automatisieren Sie Webaufgaben mit einem leichten, leistungsstarken Browser, der für KI-Agenten entwickelt wurde.

Was ist ego-lite?

Diese Fähigkeit stellt einen echten Chromium-Browser über eine CLI-zugängliche Node.js-Laufzeitumgebung bereit, die speziell für KI-Agenten optimiert ist. Sie bietet Playwright-ähnliche Schnittstellen wie `page`, `page.locator(...)`, `browser` und `taskSpaces` sowie einzigartige Funktionen wie `site`, `fetch` und `cdp`. Die Fähigkeit ist für folgende Plattformen konzipiert: Claude Code, Cursor, Codex und andere KI-Agenten-Entwicklungsumgebungen, die Bash-Tools und Node.js-Scripting unterstützen. Der Hauptvorteil liegt im Design mit einer einzigen Bash-Invokation, bei dem jede vorhersehbare Beobachtung, Aktion, Wartezeit, Extraktion und Verifizierung in einem einzigen JavaScript-Heredoc innerhalb eines Bash-Befehls gekapselt wird. Dies eliminiert den Overhead von mehreren Tool-Aufrufen und reduziert die Latenz, was es ideal für die leichte, leistungsstarke Webautomatisierung macht. Der Agent interagiert mit dem Browser durch direkte JavaScript-APIs, verwaltet mehrere Tabs über `browser.listTabs()` und `browser.switchTab()`, handhabt komplexe Navigations- und Formularinteraktionen und verwendet `taskSpaces` für isolierte Browsing-Kontexte, die den Login-Zustand des Benutzers erben. Die Fähigkeit legt einen starken Schwerpunkt auf Zustandsmanagement, Aufgabenabschlussprotokolle und das Einfrieren von Zeitfenstern für datumsbezogene Aufgaben, was eine zuverlässige und deterministische Ausführung gewährleistet.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add fourth3950/ego-lite

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

ego-browser

ego-browser stellt einen echten Chromium-Browser über eine CLI-zugängliche Node.js-Laufzeitumgebung bereit. Seine vorinstallierten Fassaden page, page.locator(...), browser und taskSpaces folgen Playwright-ähnlichen Namen und Aufrufstrukturen; taskSpaces, site, fetch und cdp bieten ego-browser-spezifische Fähigkeiten.

Informationen zu Einrichtung, Installation oder Verbindungsproblemen finden Sie in references/install.md.

Führen Sie Browserarbeit mit dem Bash-Tool als ego-browser nodejs <<'EOF' ... EOF aus. Platzieren Sie das JavaScript direkt im Heredoc; erstellen Sie keine .js-Datei, importieren Sie Playwright nicht, starten Sie keinen weiteren Browser und erfinden Sie keine Hilfsnamen.

Ein Heredoc ist nur der JavaScript-Container; die Bash-Invokation ist der Ausführungsdurchlauf. Standardmäßig wird eine Bash-Invokation für die gesamte Browseraufgabe verwendet. Jedes await ist eine interne Operation, keine Schrittgrenze. Kodieren Sie vor dem Start jede vorhersehbare Beobachtung, Aktion, Wartezeit, Extraktion, Verifizierung und begrenzte Alternative im Skript. Verwenden Sie Browserergebnisse sofort in JavaScript und passen Sie sich weiterhin innerhalb des Prozesses an, bis die Aufgabe abgeschlossen ist; beenden Sie das Skript nicht nur, um die Zwischenausgabe zu inspizieren oder die nächste Aktion zu planen. Starten Sie einen anderen Bash-Befehl nur für eine erforderliche Benutzer- oder externe Steuerung, eine visuelle Inspektion, die nicht innerhalb des Prozesses erfolgen kann, oder einen Fehler auf Prozessebene, von dem sich das Skript nicht erholen kann.

Wählen Sie den zustandsärmsten zuverlässigen Weg, bevor Sie Seitensteuerelemente inspizieren. Wenn die Aufgabe ein Ergebnis oder Einschränkungen, aber keine erforderliche Interaktion vorgibt, bevorzugen Sie einen bereits korrekten Zustand oder eine bekannte stabile URL oder Websiteroute, die diese direkt kodiert; verifizieren Sie den resultierenden Zielzustand, anstatt gleichwertige Filter, Sortierungen oder Navigation über die Benutzeroberfläche nachzuspielen. Verwenden Sie Seitensteuerelemente, wenn der Benutzer diese Interaktion angefordert hat, die Interaktion selbst getestet wird oder kein zuverlässiges Äquivalent bekannt ist. Erfinden Sie niemals eine fragile Route.

Behandeln Sie eine bereits erfüllte Nachbedingung als abgeschlossene Arbeit. Bevor Sie ein Steuerelement manipulieren, dessen erforderlicher Wert möglicherweise bereits sichtbar ist, führen Sie nur die kleinste Leseoperation durch, die erforderlich ist, um diesen Zustand zu bestimmen. Wenn er übereinstimmt, öffnen Sie nicht den Editor, spielen Sie die Interaktion nicht nach und lesen Sie ihn nicht erneut; fahren Sie direkt mit den verbleibenden unerfüllten Ergebnissen fort. Wörter wie „setzen“, „auswählen“ oder „sicherstellen“ beschreiben den erforderlichen Endzustand, es sei denn, der Benutzer fordert explizit den Übergang oder die Interaktion selbst wird getestet.

Trennen Sie Browserarbeit vom Terminalabschluss. useOrCreate beginnt oder setzt ein Benutzerziel fort; behalten Sie die zurückgegebene task.id und verwenden Sie dieselbe ID oder denselben genauen Namen, bis dieses Ziel beendet ist. Halten Sie jede vorhersehbare Beobachtung, Aktion, Wartezeit, Extraktion und Verifizierung kompakt, aber rufen Sie taskSpaces.complete(...) nicht in einer Bash-Invokation auf, die noch feststellt, ob das Ziel erfüllt ist. Schließen Sie zuerst die Browserarbeit ab und geben Sie Nachweise aus, dass jedes angeforderte Ergebnis sowie alle erforderlichen Umfangs- oder Abdeckungsgrenzen nachgewiesen wurden. Erst nachdem Sie diese vorherige Ausgabe überprüft haben, darf eine dedizierte letzte Bash-Invokation den ursprünglichen Aufgabenbereich abschließen; sie führt keine page- oder browser-Arbeit aus. Dieser einzelne Lebenszyklus-Commit ist die Ausnahme von der Standardeinstellung mit einer Invokation, kein Browser-Schritt oder -Durchlauf. Nicht leere oder plausible Teilergebnisse, eine blockierte Seite, erschöpfte Wiederholungen oder ein Fallback-Versuch sind keine Abschlussnachweise. keep: true bewahrt ein terminales Ergebnis für den Benutzer; es hält keine unvollendete Aufgabe am Leben.

Frieren Sie das Zeitfenster für aktuelle oder relative Datumsarbeit ein. Legen Sie „heute/aktuell/neueste“ einmal aus der Benutzer-/Aufgabenumgebung oder dem explizit verifizierten aktuellen Seitenzustand fest, bevor Sie Datensätze sammeln. Behandeln Sie Inhaltszeitstempel als Daten, nicht als Uhr. Ältere Datensätze, die durch Scrollen, Virtualisierung, Neuladen, Cache oder eine geänderte Ergebnismenge aufgedeckt werden, dürfen diesen Anker nicht ersetzen. Fahren Sie mit der Bewertung von Datensätzen anhand des ursprünglichen Fensters fort; führen Sie die Aufgabe nicht stillschweigend auf das neueste beobachtete Inhaltsdatum zurück.

Kurzstart

Jedes Beispiel in dieser Fähigkeit ist bewusst zusammengesetzt. Passen Sie URL, Selektoren und Daten an die Benutzeraufgabe an.

ego-browser nodejs <<'EOF'
const task = await taskSpaces.useOrCreate('Beispielseite inspizieren')
await browser.openOrReuseTab('https://example.com', { wait: true, timeout: 20000 })

const heading = await page.getByRole('heading').first().innerText()
const info = await page.info()
if (!heading || !('url' in info)) throw new Error('Beispielseite war nicht bereit')

const result = { taskSpaceId: task.id, heading, url: info.url }
console.log(JSON.stringify(result, null, 2))
EOF

Behalten Sie alle vorhersehbaren Arbeiten im Skript, bis die Aufgabe abgeschlossen ist. Geben Sie Endergebnisse mit console.log(...) aus.

Zusammengesetzte Muster

Extrahieren, auswählen, navigieren, verifizieren

Extrahieren Sie auf einer Listen- oder Suchseite strukturierte Kandidaten, bevor Sie eine Auswahl treffen. Behalten Sie Extraktion, Auswahl, Aktion, Wartezeit, Verifizierung und Bereinigung in einer Bash-Invokation.

ego-browser nodejs <<'EOF'
const task = await taskSpaces.useOrCreate('Suchergebnisse vergleichen')
await browser.openOrReuseTab('https://example.com/search?q=browser+automation', {
  wait: true,
  timeout: 20000,
})

const cards = page.locator('article')
const items = await cards.evaluateAll((nodes) =>
  nodes.map((node) => ({
    title: node.querySelector('h2')?.textContent?.trim(),
    href: node.querySelector('a')?.href,
  })),
)
const chosenIndex = items.findIndex((item) => item.title && item.href)
if (chosenIndex < 0) throw new Error('Kein brauchbares Ergebnis: ' + JSON.stringify(items))

const before = await page.url()
const navigation = page.waitForURL((url) => url.href !== before, { timeout: 15000 })
await cards.nth(chosenIndex).getByRole('link').first().click()
if (!(await navigation)) throw new Error('Ausgewähltes Ergebnis hat nicht navigiert')

const info = await page.info()
if (!('url' in info) || info.url === before) throw new Error('Navigation wurde nicht verifiziert')
const result = { chosen: items[chosenIndex], opened: info.url }
console.log(JSON.stringify(result, null, 2))
EOF

Ausfüllen, auslösen, warten, zurücklesen

Registrieren Sie Request-/Response-Wartezeiten vor der Aktion, die sie auslöst, und verifizieren Sie dann den resultierenden Seitenzustand, anstatt den Klick als Erfolg zu behandeln.

ego-browser nodejs <<'EOF'
const task = await taskSpaces.useOrCreate('Bestellungen durchsuchen')
await browser.openOrReuseTab('https://example.com/orders', { wait: true, timeout: 20000 })

const responsePromise = page.waitForResponse(
  (response) => response.url().includes('/api/orders') && response.ok(),
  { timeout: 15000 },
)
await page.getByLabel('Bestellungen durchsuchen').fill('ausstehend')
await page.getByRole('button', { name: /suchen/i }).click()
const response = await responsePromise

const rows = await page.locator('table tbody tr').allInnerTexts()
if (!rows.length) throw new Error('Suche abgeschlossen, aber keine sichtbaren Zeilen zurückgegeben')
const result = { status: response.status(), rows }
console.log(JSON.stringify(result, null, 2))
EOF

Tab-Handles aktualisieren, wechseln, inspizieren

Behandeln Sie targetId als kurzlebiges Handle. Entdecken, validieren und verwenden Sie es in derselben Bash-Invokation.

ego-browser nodejs <<'EOF'
const task = await taskSpaces.useOrCreate('Generierten Bericht überprüfen')
const tabs = await browser.listTabs({ includeChrome: false })
const reportTab = tabs.find((tab) => tab.url.includes('/reports/'))
if (!reportTab?.targetId) throw new Error('Bericht-Tab nicht gefunden: ' + JSON.stringify(tabs))

await browser.switchTab(reportTab.targetId)
const info = await page.info()
const heading = await page.getByRole('heading').first().innerText()
if (!('url' in info) || !info.url.includes('/reports/')) throw new Error('Falscher Tab ausgewählt')
const result = { taskSpaceId: task.id, heading, url: info.url }
console.log(JSON.stringify(result, null, 2))
EOF

Laufzeitübersicht

  • page: Navigation und Zustand (goto, reload, url, title, info), semantische Locators, Wartezeiten, snapshot, screenshot, screencast, evaluate, keyboard, mouse, Downloads und Ereignisverarbeitung.
  • page.locator(selector): Verkettung und Filterung; first / nth / last; Klick, Hover, dragTo, scrollIntoViewIfNeeded, Formular-, Tastatur-, Upload-, Zustandslese-, Sammlungs-, Element-Evaluierungs-, Screenshot- und Wartemethoden.
  • browser: listTabs, currentTab, switchTab, openOrReuseTab, closeTab, ensureRealTab, iframeTarget.
  • taskSpaces: list, switch, new, useOrCreate, claim, complete, handOff, takeOver, waitForAgentControl.
  • fetch.server führt Node-seitige Requests aus; fetch.browser führt Requests im Ursprung der aktuellen Seite aus. Verwenden Sie cdp nur als Notluke.
  • console.log ist der Ausgabekanal. Verwenden Sie console.log(help('page')), console.log(help('locator')) oder einen anderen help(name)-Aufruf, wenn eine genaue Signatur unklar ist.

Ausführungsregeln

  • page.url() ist asynchron in ego-browser; verwenden Sie immer await page.url(). Ein page.waitForURL(...)-Prädikat empfängt ein URL-Objekt, also inspizieren Sie url.href, url.pathname oder url.searchParams. Es wartet standardmäßig auf load; verwenden Sie waitUntil: 'commit' nur, wenn Sie absichtlich vor dem Laden fortfahren.
  • page.waitForURL, page.waitForLoadState, page.waitForSelector, Locator waitFor und page.waitForFunction geben bei Zeitüberschreitung einen falsy-Wert zurück. Überprüfen Sie das Ergebnis oder verifizieren Sie sofort den erforderlichen Zustand, bevor Sie fortfahren.
  • Registrieren Sie Request-, Response- oder Navigationswartezeiten vor der Aktion, die sie auslöst. Bevorzugen Sie zustandsbasierte Wartezeiten; verwenden Sie page.waitForTimeout(...) nur für kurze visuelle Beruhigung und halten Sie es bei oder unter 2000 ms.
  • Bevorzugen Sie stabile semantische Locators. Wenn die Seitenstruktur unbekannt ist, sammeln Sie die relevanten Steuerelemente oder Kandidaten einmal mit evaluateAll, allInnerTexts oder einer anderen begrenzten Leseoperation, leiten Sie die nächsten Aktionen in JavaScript ab und fahren Sie im selben Heredoc fort, anstatt Selektorversuche über Befehle hinweg aufzulisten.
  • Einzelelement-Aktionen und erforderliche Leseoperationen – einschließlich roher CSS- und roher xpath=-Locators – sind strikt und warten automatisch. Bei null Treffern überprüfen Sie den Ladezustand, den aktiven Tab und den Modal-/Overlay-Zustand, bevor Sie den Locator korrigieren. Bei mehreren Treffern inspizieren Sie count() / allInnerTexts(), grenzen Sie semantisch oder mit filter(...) ein und verwenden Sie first() / nth() erst, nachdem Sie bestätigt haben, dass Duplikate legitim sind. Lassen Sie eine erfolgreiche Aktion das Skript voranbringen; lesen Sie den Zustand, wenn er einen Zweig bestimmt, und einmal für die erforderlichen endgültigen Nachbedingungen der Aufgabe, nicht nach jeder Aktion. Ein bereits erfüllter erforderlicher Zustand benötigt keine Wiederholung.
  • Verwenden Sie bei Fehlern eine gezielte Beobachtung, um die Strategie wesentlich zu ändern. Wiederholen Sie keine nahezu identischen Locators oder Befehle; wechseln Sie basierend auf den Beweisen zu einem stabilen semantischen, DOM- oder visuellen Pfad.
  • Bewahren Sie explizit angeforderte, für den Benutzer sichtbare Übergänge und Stopp-Grenzen. Wenn ein erforderlicher Klick den aktuellen Tab navigieren oder einen anderen öffnen kann, klicken Sie einmal und lösen Sie das Ergebnis aus await page.url() plus einem aktualisierten browser.listTabs() im selben Skript; ersetzen Sie den Klick nicht durch direkte Navigation, nur weil das Ziel bekannt ist. Schlucken Sie keine Fehler von erforderlichen Aktionen.

Aufgabenbereiche

Ein Aufgabenbereich ist ein isolierter Browsing-Kontext mit eigenen Tabs, der den Login-Zustand des Benutzers erbt. Wählen Sie ihn einmal zu Beginn des ersten Bash-Skripts mit taskSpaces.useOrCreate(nameOrId) aus. Wenn eine externe Abhängigkeit einen späteren Befehl unvermeidlich macht, wählen Sie dieselbe zurückgegebene numerische task.id oder denselben genauen kurzen Zielnamen, bevor Sie fortfahren; erstellen Sie einen neuen Bereich nur für ein separates Benutzerziel. Bewahren Sie bereits verifizierte Fakten über Befehle hinweg, anstatt die Einrichtung neu zu starten.

useOrCreate verwendet oder erstellt agenteneigene Bereiche wieder. Wenn der passende Bereich benutzereigen ist, wird der Bereich ausgewählt, ohne ihn zu beanspruchen, sodass Browserarbeit auf die harte Grenze der Benutzersteuerung stößt. Nach expliziter Benutzerbestätigung, dort zu arbeiten, verwenden Sie taskSpaces.list() → taskSpaces.claim(id) → browser.listTabs() → browser.switchTab(targetId).

Jeder Bereich hat ownership: 'agent' | 'agentDelegatedToUser' | 'user':

Operation auf einem benutzereigenen BereichVerhalten
taskSpaces.switchWirft einen Fehler; es wechselt nur agenteneigene Bereiche
taskSpaces.claimÜberträgt das Eigentum an den Agenten und wählt den Bereich aus
taskSpaces.handOff / complete(..., { keep: true })Überspringt mit { done: false, skipped: 'user-owned' }
taskSpaces.complete(..., { keep: false })Beansprucht, schließt dann den Bereich
taskSpaces.takeOver / waitForAgentControlFührt keine Eigentumsprüfung durch

Überprüfen Sie das done-Ergebnis von handOff und complete, bevor Sie den Erfolg beanspruchen.

Behandeln Sie den Abschluss als terminalen Commit, getrennt von der Browserausführung. Beenden Sie die arbeitende Bash-Invokation ohne Abschluss, nachdem Sie die endgültige URL, Werte und andere Nachweise erfasst und ausgegeben haben. Überprüfen Sie diese Ausgabe: Jede angeforderte Nachbedingung und alle erforderlichen Umfangs- oder Abdeckungsgrenzen müssen nachgewiesen sein, nicht nur wahrscheinlich. Wenn sie nachgewiesen sind, führen Sie eine dedizierte letzte Bash-Invokation aus, die taskSpaces.complete(nameOrId, { keep }) höchstens einmal für die ursprüngliche ID oder den genauen Namen aufruft, done überprüft und keine page- oder browser-Arbeit ausführt. Wenn etwas nicht erfüllt oder nicht nachgewiesen ist, fahren Sie stattdessen im selben ursprünglichen Aufgabenbereich fort; eine Korrektur, Wiederholung oder spätere Phase ist kein neues Ziel. keep ist erforderlich. Standard ist false; verwenden Sie true nur, wenn der Benutzer darum gebeten hat, die fertige Seite zu behalten, manuell darin handeln muss oder das Ergebnis nicht als URL, Datei, Artefakt oder Zusammenfassung geliefert werden kann. Schließen Sie temporäre Tabs nach und nach und behalten Sie nur die Tabs, die der Benutzer benötigt.

Kodieren Sie niemals eine targetId fest, kopieren Sie sie nicht von Hand und benennen Sie sie nicht in id um. Besorgen und verwenden Sie sie innerhalb der aktuellen Bash-Invokation. Wenn ein anderer Befehl wirklich notwendig ist, aktualisieren Sie browser.listTabs() und validieren Sie find(...)-Ergebnisse, bevor Sie wechseln oder schließen. browser.iframeTarget(...) gibt eine Ziel-ID-Zeichenfolge oder null zurück, kein Objekt.

Steuerungsübergabe

Ein Fehler „Benutzer steuert“, „inaktiv“ oder „nicht zugewiesen“ ist ein harter Stopp für die gesamte Aufgabe. Wiederholen Sie es nicht, umgehen Sie es nicht und rufen Sie nicht automatisch taskSpaces.takeOver auf. Fragen Sie den Benutzer und warten Sie.

Für Login, Captcha oder einen anderen manuellen Schritt schließen Sie …

Verwandte Skills