big-arrow-on-the-screen (bigarrow)

Je AI-agent kan een monorepo refactoren, een migratie schrijven en monaden uitleggen, maar wanneer hij wil dat je op één knop klikt, print hij "klik op 'Sta toe' in de dialoog" in een terminal waar je niet naar kijkt. bigarrow geeft de agent een vinger om mee te wijzen.

Voorbeeld: bigarrow point --element "Allow" --app "System Settings" --text "Franz, klik op Sta toe"

Er verschijnt een grote, vriendelijke pijl met een bordje bovenop alles, wijst naar het object en verdwijnt vervolgens weer. Het is doorklikbaar, steelt nooit je focus, werkt op elk scherm en elke Space, en heeft geen speciale rechten nodig om te tekenen. Het is één klein Swift-binair bestand. Er is geen daemon, geen menu-balkicoon, geen account, geen telemetrie en — we hebben het dubbel gecheckt — geen AI ingebouwd. Het is gewoon een pijl.

Waar is dit eigenlijk voor bedoeld?

Pijlen bestaan al sinds het Paleolithicum, maar de context is veranderd: software-agents voeren nu echt werk uit op je Mac, maar lopen telkens tegen dezelfde muur aan: het deel dat alleen een mens mag doen.

  • "Klik op Sta toe": macOS-machtigingsprompts, OAuth-toestemmingsschermen, "Openen met...?" dialoogvensters. De agent kan de knop vinden, maar mag of kan hem niet voor jou indrukken. Hij kan er nu wel naar wijzen.
  • "Nu jij": 2FA-codes, CAPTCHA's, passkeys, een betalingsbevestiging, een handtekening, een juridisch selectievakje. Zaken die een agent nooit namens zichzelf mag aanklikken. De agent wijst, jij beslist, de agent gaat verder.
  • "Het is dit venster, niet dat een": Je hebt 14 Chrome-vensters open. De agent weet precies welke hij bedoelt: --window "Google Chrome:Pull request". Hij kiest zelfs het juiste tabblad: --app "Google Chrome:Pull request".
  • "Ik heb je nodig, en jij bent koffie aan het zetten": --say leest het bordje hardop voor. Je Mac roept je letterlijk terug naar je bureau.
  • Begeleide installaties en onboarding: Begeleid een mens stap voor stap door een instellingenpaneel: start, wacht tot er actie is ondernomen, stop, volgende stap. Als een producttour, maar dan zonder het product.
  • Hulp op afstand: In plaats van "het andere tandwiel-icoontje" te beschrijven, wijst de agent er simpelweg naar.
  • Demo's, screencasts, documentatie: Markeer wat belangrijk is tijdens het opnemen, of render de pijl direct naar een PNG met --png voor documentatie.
  • Debugging van coördinaten: Niet zeker of je Accessibility-, screenshot- of Peekaboo-coördinaten correct zijn? Wijs ernaar en kijk. --dry-run --json vertelt je waar hij zou wijzen zonder daadwerkelijk iets te tekenen.

Situaties die we allemaal kennen

(Gebaseerd op demo-scenario's met BACKDROP_ARGS=--cover scripts/funny-scenes.sh)

  • --color green
  • --shape zigzag --color orange
  • --color purple
  • --close-button, omdat de mens het laatste woord heeft.
  • Drie pijlen, één knop, nul ambiguïteit.
  • --style box --corners sharp, plus een les over macOS-machtigingen.
  • --shape spiral: één keer rond het bordje, dan naar de knop.

Wat het niet is: Het is geen scherm-annoteerder voor mensen, geen klik-bot of screenshot-tool. Het klikt, typt of capturet nooit iets. Het wijst alleen. Bewust.

Installatie

Via Homebrew: brew install franzenzenhofer/tap/bigarrow

Installatie van de skill: bigarrow install-skill (leert Claude Code ~/.claude/skills en Codex ~/.agents/skills)

Vanuit broncode: swift build -c release (Xcode 16 of nieuwer, macOS 14 of nieuwer), binair bestand op .build/release/bigarrow.

De drie commando's die een agent nodig heeft

  1. bigarrow point --element "Allow" --app "System Settings" --text "Franz, klik op Sta toe" (op basis van label)
  2. bigarrow point --at 760,500 --text "Franz, klik HIER" (op basis van coördinaten)
  3. bigarrow start --window "Safari:Inbox" --text "Dit venster" && bigarrow stop (totdat gestopt)

Automatisch beheer van pijlen

Elke pijl eindigt vanzelf. Niemand hoeft op te ruimen na een agent die iets is vergeten:

  • Tijdslimiet: bigarrow point ... --duration 10 (standaard 8 s; start 300 s; --duration 0 = geen limiet).
  • Start en stop: bigarrow start ... keert onmiddellijk terug; bigarrow stop (of stop --all) verwijdert de pijl.
  • De agent vertrekt: Een pijl eindigt wanneer het agent-proces dat hem tekende afsluit (CLAUDEPID of BIGARROWOWNER_PID).
  • De mens antwoordt: bigarrow stop --hook als een Claude Code UserPromptSubmit hook wist de pijlen van die sessie.
  • De mens sluit hem: --close-button plaatst een klikbare X op het bordje (optioneel).

Targets en positionering

Targets kunnen zijn: --at X,Y, --rect X,Y,W,H, --mouse, --window App[:title], --element Label --app App, --peekaboo ID --snapshot see.json (van Peekaboo's see --json). Coördinaten zijn globale top-left logische punten, zoals gerapporteerd door Accessibility, CGWindowList en Peekaboo. --display N maakt --at en --rect relatief aan één specifiek scherm.

Een pijl is gekoppeld aan de app waar hij naar wijst. --app App[:window or tab title] (of --window) brengt die app, dat venster of dat Chrome/Safari-tabblad eerst op de voorgrond, omdat wijzen naar een venster dat achter je terminal verborgen is, niet nuttig is. Terwijl een andere app het doel bedekt, verbergt de pijl zich en komt hij weer tevoorschijn zodra het doel zichtbaar is. --no-raise laat je vensters ongemoeid.

bigarrow elements --app X lijst op waar --element op kan matchen. bigarrow doctor toont machtigingen, wie de eigenaar is en je schermen.

Elk commando accepteert --json. Exit codes: 0 ok, 2 slechte invoer, 3 target niet gevonden, 4 machtiging ontbreekt. Agents houden van exit codes; mensen tolereren ze.

Visuele weergave

Er is veel tijd besteed aan het uiterlijk. De pijl is getest op diverse achtergronden (wit, macOS grijs, donker, zwart, rood en drukke webpagina's).

  • Vorm (--shape): bend | straight | zigzag | spiral (zigzag voor dringende zaken; spiral draait één keer om het bordje voordat hij wijst, zodat hij onmogelijk te missen is).
  • Stijl (--style): arrow | ring | box (ringen en boxen zijn alleen randen, zodat je nog ziet wat eronder staat).
  • Grootte en hoeken: --size S|M|L, --corners round|sharp.
  • Kleur (--color): red|orange|yellow|green|teal|blue|purple|pink|black|white|#RRGGBB.
  • Rand (--border): shadow|white-black|black. Standaard is een witte rand (donker op lichte kleuren) met een schaduw; white-black plaatst een dunne zwarte rand buiten de witte rand in plaats van de schaduw; black is een dunne zwarte omlijning.

Aanvullende kleuren: Gebruik --border-color, --text-color, --edge-color, en voor de X: --close-color en --close-x-color. Indien weggelaten, kiest de tool zelf een leesbare kleur.

Extra opties:

  • --close-button: plaatst een X in het rechteruiteinde van het bordje (witte cirkel, X in de kleur van de pijl).
  • --follow: beweegt mee met een venster of element.
  • --until-click: eindigt bij een klik op het target.
  • --say: spreekt de tekst op het bordje uit.

Meerdere pijlen tegelijkertijd houden hun bordjes uit elkaars weg. De schacht groeit uit het bordje via een verbreding (flared joint) die nooit in een afgeronde hoek loopt.

FAQ

Heeft het Screen Recording of Accessibility nodig? Tekenfunctionaliteit heeft geen van beide nodig. --element, elements, --until-click en front --window maken gebruik van Accessibility. macOS verleent dit recht aan de app die je shell uitvoert (Terminal, iTerm2, Ghostty, VS Code, Claude), nooit aan bigarrow zelf. bigarrow doctor noemt die app, en exit code 4 vertelt de agent precies waar hij je om moet vragen. --window App:title leest venstertitels, wat macOS 26 verbergt zonder Screen Recording; --window App alleen heeft niets nodig.

Zal het mijn focus stelen terwijl ik typ? Nee. NSApplication.run() activeert normaal gesproken een proces zonder terminal, waardoor losgekoppelde pijlen de focus konden grijpen. bigarrow pompt events zelf, en tests controleren dat de voorste app nooit verandert.

Kan ik erdoorheen klikken? Ja, overal behalve op het bordje en de schacht: een klik daar verwijdert de pijl (deze dimt lichtjes onder de aanwijzer om dit aan te geven). Een klik op het doel, of overal in de buurt van de pijlpunt, gaat direct door naar de app. Klikken op de pijl neemt nooit de focus over.

Meerdere schermen? Full-screen apps? Stage Manager? Spaces? Ja, ja, ja, ja. Schermen links van of boven de hoofdmonitor (negatieve coördinaten) zijn inbegrepen. Als je een scherm loskoppelt terwijl er een pijl op staat, verdwijnt de pijl netjes.

Hoeveel CPU kost een pulserende pijl? Gemeten op 1,4% op een CI-runner. Core Animation doet het werk in de render server.

Werkt --element binnen webpagina's? In Electron-apps: ja. In Chrome: alleen wanneer Chrome wordt uitgevoerd met --force-renderer-accessibility (of VoiceOver is aan); Chrome negeert normaal gesproken het verzoek om pagina-inhoud bloot te leggen (geverifieerd in oktober 2026). De eigen toolbar van Chrome werkt altijd. Anders kan men wijzen naar de coördinaten van de pagina, wat de skill uitlegt.

Waarom niet gewoon een scherm-annoteer-app gebruiken? Die zijn voor mensen die op schermen tekenen. Dit is voor programma's die naar dingen wijzen, vanuit een shell, met exit codes. Er zijn zesentwintig tools gecontroleerd voordat er een regel code werd geschreven; geen enkele deed dit.

Is het AI? Nee. Het is het minst intelligente onderdeel van je AI-stack, en trots daarop.

Kwaliteitsborging

  • 87 geautomatiseerde tests: geometrie, plaatsing, gladheid van verbindingen, een golden image, opgenomen window-server, Accessibility en Peekaboo 4.9.0 fixtures, en tests tegen de echte window server (window level 1000, clicks pass through, focus moves not, detach and stop timing). CI draait deze op macOS 15; ze zijn ook geslaagd op macOS 26 en macOS 27.
  • 17 gedragscontroles op een schone runner (visual.yml): echte klikken op de X, --until-click, --follow, raising (en --no-raise), verbergen terwijl bedekt, selecteren van een Chrome-tab, beëindigen met het owner-proces, stop --hook, --say, full-screen apps, Stage Manager, een Space-switch, een tweede scherm, een 2x scherm, loskoppelen van een scherm tijdens een pijl, CPU.
  • Agent-test: Een nieuwe agent die alleen de skill kreeg en de opdracht "laat Franz zien waar de Reload-knop in Chrome is", vond deze via het label en bouwde het juiste commando.

Voor agents (en de mensen die hen configureren)

De skill in skill/big-arrow/ werkt voor zowel Claude Code als Codex (één SKILL.md, Agent Skills formaat, plus agents/openai.yaml voor Codex). Het vertelt de agent wanneer hij moet wijzen, hoe hij een target kiest, hoe hij een volledige zin op het bordje schrijft, om --say toe te voegen wanneer je waarschijnlijk niet kijkt, en om te stoppen zodra je actie hebt ondernomen.

Planning, beslissingen en onderzoek

Documentatie is beschikbaar in:

  • docs/plan/PLAN.md (doel, architectuur, risico's)
  • docs/plan/TICKETS.md (gegenereerd uit docs/plan/tickets.json)
  • docs/decisions/
  • docs/research/ (geverifieerde feiten met links)
  • docs/verification/
  • docs/skill-tests/
  • CHANGELOG.md

Eerdere werken en dankwoord

De visualizer van Peekaboo (https://github.com/openclaw/Peekaboo) en Nameplate (https://github.com/steipete/Nameplate) van Peter Steinberger toonden het recept voor het overlay-venster en de verpakking van de agent-skill. Geen van beide tekent echter een wijzende pijl met een label, wat het gat is dat dit project vult. bigarrow leest Peekaboo's see --json als een optionele bron voor targets.

Licentie

MIT. Wijs verantwoord.