The Closing Window
Ein Notizen-Plugin für alle, die ihre Agent-Sessions ausreizen image
Photo by Amanda Jones on Unsplash

Ein Notizen-Plugin für alle, die ihre Agent-Sessions ausreizen

AI Insights

Vorab ein Wort dazu, wie dieser Text entstanden ist

Dieser Beitrag wurde größtenteils von einer KI geschrieben. Das will ich gleich zu Anfang sagen, weil ich immer öfter sehe, dass Publikationen KI-generierte Inhalte pauschal verbieten, und ich halte das für einen Fehler.

Ich bin Ingenieur, kein Autor. Schreiben kostet mich echte Mühe. Meistens mache ich es trotzdem, weil es mir Spaß macht und weil es mich zwingt, ein Thema wirklich zu durchdenken, was sich für sich genommen schon lohnt. Es bringt mir Klarheit. Aber das sind ein paar Stunden, die ich nicht immer habe.

Die Wahl, vor der ich diese Woche stand, war also nicht "guter Text oder KI-Text". Sie war "KI-Text oder gar kein Text". Ich habe etwas wirklich Nützliches gefunden, fast zufällig, und ich habe es in genau einem Newsletter erwähnt gesehen. Sonst nirgends. Wenn der Preis dafür, das zu teilen, darin besteht zuzugeben, dass ein Modell mir beim Sortieren der Sätze geholfen hat, dann ist das eben so.

Das pauschale Verbot behandelt "KI-generiert" als Stellvertreter für "wertlos". Manchmal stimmt das. Es wird eine Menge Müll für Klicks rausgehauen, und davon verteidige ich nichts. Aber der Stellvertreter taugt nicht. Worauf es ankommt, ist, ob darunter etwas Echtes liegt: eine Entdeckung, ein Bug, den du tatsächlich getroffen hast, ein Ding, das du tatsächlich gebaut hast. Beurteile das. Ich mache das hier nicht für Engagement-Zahlen. Ich mache es, weil ich glaube, dass drei oder vier Leute, die das lesen, dieses Ding installieren werden und froh darüber sein werden.

Wie auch immer. Weiter zum wichtigen Teil.


TL;DR

Ich wollte ständig Notizen für mich selbst innerhalb einer Agent-Session hinterlassen. Es gab keinen guten Weg dafür. Die Optionen recherchiert, die meisten schlecht. Dann tauchte in einem Newsletter eine Agent-IDE namens bb auf, und das war das eine Tool, bei dem ich das fehlende Feature einfach selbst bauen konnte. Zwanzig Minuten, plus minus. Plugin gibt's hier, MIT.

Das eigentliche Problem: Notizen überleben, ihr Kontext nicht

Wenn du den ganzen Tag mit Coding-Agenten arbeitest, kennst du das schon.

Du setzt Claude auf eine Aufgabe an. Er arbeitet sie durch und wird fertig. Die Aufgabe ist wirklich erledigt.

Und dann, im selben Atemzug, erzählt er dir von drei weiteren Dingen. Eine Funktion, die falsch ist, aber außerhalb des Scopes lag. Ein Config-Wert, der den Docs widerspricht. Ein Test, der seit März übersprungen wird. Alles echt, alles verwandt mit dem, was du gerade gemacht hast, und nichts davon das, wonach du gefragt hast. Gute Agenten bringen sowas zur Sprache. Claude bringt eine Menge davon zur Sprache.

Das Timing ist das Problem. Dieser Moment ist ohnehin schon der geschäftigste im ganzen Zyklus. Die Arbeit liegt in einem Worktree, ich muss mir also noch ansehen, was sich tatsächlich geändert hat, es laufen lassen, entscheiden, ob ich es glaube, und den Branch zurück nach main mergen. Das ist die akute Verpflichtung, und die hat meine Aufmerksamkeit.

Drei echte Funde kommen also genau in dem Moment an, in dem ich am wenigsten Platz für sie habe, und sie konkurrieren mit einem Merge um dieselbe Scheibe meines Kopfes. Was mit ihnen als Nächstes passiert, muss innerhalb einer Minute passieren, denn danach stecke ich im Diff.

Lange Zeit war das, was als Nächstes passierte, eine Task-App oder eine Todo-Datei in Plaintext, die ich in etwas anderem geöffnet habe. Ich habe eine Weile in Warp gelebt, dann in Superset, und dabei immer drei Terminal-Fenster über mindestens ebenso viele Projekte hinweg jongliert.

Und ich habe diese Listen gepflegt. Eine pro Projekt, akribisch abgearbeitet, jeder Punkt irgendwann nachverfolgt. Nichts ist untergegangen.

Es war trotzdem das falsche System, aus zwei Gründen, die ich eine Weile gebraucht habe, um sie auseinanderzuhalten.

Der erste ist, dass mich das Aufschreiben die Session gekostet hat. Einen Gedanken festzuhalten hieß: raus aus dem, was ich gerade mittendrin machte, rüber in eine andere Anwendung, eintippen, zurückkommen. Sagen wir fünfzehn Sekunden. Fünfzehn Sekunden reichen völlig. Das ist genau das Fenster, in dem ich die Form dessen, was der Agent gerade getan hat, noch im Kopf halte, und jeder dieser Wege schlägt ein kleines Loch hinein. Mach das sechsmal an einem Nachmittag, und der Nachmittag geht dafür drauf, deinen Platz wiederzufinden. Die Liste zu pflegen war nie das Schwierige. Die Unterbrechung, die sie jedes einzelne Mal verlangt hat, schon.

Der zweite ist schlimmer, und der hat das hier tatsächlich angetrieben. Eine Aufgabe in einer anderen App hat keine Möglichkeit, ihren Kontext mitzunehmen. Ich schrieb "die Retry-Logik im Sync-Handler prüfen", und einen halben Tag und 1 Million Tokens später las ich das zurück, und der Satz war technisch klar und praktisch nutzlos. Warum hatte ich das markiert? Was hat Claude gemacht, als es aufkam? Was stand im Output, das mich denken ließ, es sei wichtig? Das lag tausend Zeilen weiter oben in einem Scrollback, den ich längst geschlossen hatte.

Ich habe versucht, längere Notizen zu schreiben. Das hieß dann nur, eine Session zusammenzufassen, in der ich noch mittendrin stand, und das kostet mehr, als die Notiz wert ist.

Die Notiz überlebte also und ihre Bedeutung nicht. Am Ende habe ich die Überlegung von Grund auf rekonstruiert oder, schlimmer, dagesessen, mich halb an den Kontext erinnert und mich meistens auf Claude gestützt, um mir die Löcher füllen zu lassen.

Was ich wollte, war klein und konkret: eine Notiz hinterlassen, die am genauen Turn hängt, an dem die Sache aufkam, ohne dafür die Session zu verlassen, damit die umgebende Konversation mitkommt, wenn ich zurückkomme. Keine Notiz über den Kontext. Eine Notiz, die im Kontext lebt.

In der Praxis heißt das, dass die Notiz an der Nachricht hängt, in der Claude seine Funde aufgelistet hat. Also an der Nachricht, die die Begründung, die Dateinamen und alles andere schon enthält, was ich sonst in einen Task-Titel pressen würde, zum denkbar schlechtesten Zeitpunkt.

Was ich mir zuerst angesehen habe

Ich habe ein paar Tage damit verbracht, bevor ich irgendwas gebaut habe, und ich fasse die ganze Suche hier zusammen, weil die Form der Antwort nützlicher ist als mein Ergebnis.

Am Ende hing alles an einer Frage: muss der Agent weiterhin in einem Terminal laufen?

Wenn ja, sind die Optionen dünn. iTerm2 ist das einzige Terminal, das das wirklich kann. Es hat eine echte Annotationsfunktion, die eine Notiz an einem Textbereich in deinem Scrollback verankert, und weil es eine GUI-Aktion ist und keine Shell-Eingabe, funktioniert sie problemlos, während Claude Code das Terminal besitzt. Das ist eine legitime Antwort von der Stange, und wenn du hier aufhören und sie einfach benutzen willst, ist das ein vernünftiges Ergebnis. Warp, das ich damals benutzt habe, hat Bookmarks, die überhaupt keinen Text tragen, sie sind also Navigationsmarken und nicht mehr. In den eigenen Docs steht, dass sie verschwinden, wenn die Session schließt. kitty und WezTerm haben Positionsmarken oder Scripting-Hooks, aber keine Annotation. Ghostty hat weder noch. tmux hat nichts eingebaut, ist aber das beste Substrat, wenn du dir mit einem Popup und einem Seiten-Pane selbst etwas zusammenbauen willst.

Die eigenen Features von Claude Code bringen dich ein Stück weit und hören dann auf. Hooks können Marker in das Transkript schreiben, aber sie feuern bei Claudes Events, nicht dann, wenn mir etwas auffällt. # und /memory schreiben in CLAUDE.md, also in dauerhaftes Langzeitgedächtnis, das exakte Gegenteil von dem, was ich wollte. Slash-Commands brauchen den Prompt, an den ich mitten im Turn nicht herankomme. Session-Transkripte liegen als JSONL auf der Platte, und du kannst sie von außen ergänzen, aber nichts davon rendert live. Und die diversen Scratchpad-MCP-Server sind Nebenspeicher: die Notiz geht rein, aber sie ist an nichts verankert, womit sie genau das Problem reproduziert, dem ich entkommen wollte.

Eine Sache, die du aktiv vermeiden solltest. Falls du denkst "dann injiziere ich den Text eben von außen ins laufende Terminal": lass es. Dieser Weg führt über TIOCSTI, das eine so lange Geschichte als Werkzeug für Privilege-Escalation-Angriffe hat, dass Linux es ab 6.2 standardmäßig deaktiviert und OpenBSD es schon Jahre früher entfernt hat. Direkt auf das TTY-Device zu schreiben ist schlimmer. Diese Bytes landen mitten in dem, was der Agent gerade zeichnet, und der Bildschirm wird zu Müll.

Das Ergebnis von alldem war eine Weggabelung. Jede einzelne dieser Einschränkungen ist eine Eigenschaft von Terminals, nicht von Agenten. Output ist ein Byte-Strom in ein TTY, ein Vordergrundprozess besitzt die Eingabe, der Scrollback läuft über, und nichts hat eine stabile ID. Es gibt kein Objekt, an das man eine Notiz hängen könnte, also ist jeder Workaround in Wahrheit der Versuch, eines vorzutäuschen.

Womit die ehrlichen Optionen waren: iTerm2 nehmen und sein Modell akzeptieren, oder etwas finden, bei dem die Session aus adressierbaren Objekten statt aus Bytes besteht. Für das Zweite hatte ich keinen Kandidaten. Dann hatte ich Glück.

Der Zufall

Mitten in diesen Tagen tauchte bb in Ben's Bites auf, einem der KI-Newsletter, die ich abonniert habe.

Die Erwähnung war kurz. Sinngemäß: es ist eine Agent-IDE, und sie ist extrem anpassbar. Das hat gereicht, vor allem wegen des Zeitpunkts. Ich steckte schon tief in einem Problem, bei dem "anpassbar" die ganze Antwort war, nach der ich suchte. In jeder anderen Woche hätte ich darüber hinweggelesen.

Ich will deutlich sagen, wie viel Glück im Spiel war. Es erscheinen inzwischen jede Woche neue agentische Coding-Tools, Terminals, Orchestratoren und Wrapper. Niemand kann sie alle bewerten. Ich habe bb nicht durch Sorgfalt gefunden. Es landete in der Woche auf meinem Schreibtisch, in der ich zufällig ein Problem hatte, das seine Form hatte, und ich habe es nur erkannt, weil ich ein paar Tage damit verbracht hatte, diese Form scharf zu bekommen.

Warum es gepasst hat

bb wird unter "IDE" einsortiert, was in die Irre führt, denn du bearbeitest darin keine Dateien. Es orchestriert: es lässt Coding-Agenten (Claude Code, Codex, Cursor und alles, was ACP spricht) in benannten Threads laufen, jeder mit seinem eigenen git worktree, es ist MIT-lizenziert und läuft komplett auf deinen eigenen Maschinen mit den Abos, die du ohnehin bezahlst.

Zwei Dinge an meinem Setup haben dafür gesorgt, dass das härter einschlägt als vielleicht bei anderen.

Das Homelab. Ich lasse Jobs über mehrere Maschinen in meinem lokalen Netz laufen. Eine Kiste macht die Always-on-Agent-Arbeit, eine andere hat die GPU, der Mac Mini ist der Daily Driver. Das zu koordinieren war früher ein Haufen SSH-Sessions und viel Sich-Merken, welches Fenster welches war. bb macht das richtig: auf jeder Maschine läuft ein echter Client-Daemon, der sich zurück zum Server auf meiner Hauptmaschine verbindet. Das ist ein echter Unterschied zu SSH. Der Daemon weiß von Projekten, Environments und Providern, ich kann also einen Thread starten und sagen "führ das da drüben aus", und der Worktree wird auf diesem Host mit seinem eigenen Environment angelegt. Jede Maschine trägt außerdem eine Berechtigungsobergrenze, meine Sandbox-Kiste kann also auf vollem Zugriff stehen, während mein Laptop zugesperrt bleibt und nichts, was ich in einem Thread tue, das anheben kann.

Die zwei Modi, in denen ich arbeite. Tagsüber bin ich AI Engineer, und zu dem Job gehört immer noch, viel Software zu schreiben. Nach Feierabend bin ich das, was die Leute inzwischen einen Builder nennen, was hauptsächlich heißt, dass ich zu viele Projekte gleichzeitig laufen habe. Beide Modi sind "viele parallele Agent-Sessions, mehrere Maschinen, leicht den Faden zu verlieren". Genau dafür ist bb gebaut.

Die Features, die mich tatsächlich im Flow halten

Ich spare mir die Tour und nenne die vier Dinge, die verändert haben, wie ein Tag abläuft.

Aufgaben, die zu Threads werden. Ich kann eine Aufgabe in der App festhalten und sie mit einem Klick in einen laufenden Agent-Thread verwandeln. Klingt nach einer Kleinigkeit. Die Lücke zwischen "mir ist etwas aufgefallen" und "ein Agent arbeitet daran" ist genau die Stelle, an der meine Ideen früher steckengeblieben sind, und diese Lücke auf einen Klick zusammenzuziehen heißt, dass das Backlog dort lebt, wo ich sowieso arbeite, statt in Vikunja oder Jira darauf zu warten, dass ich zurückkomme.

Einen Thread forken. Du kannst eine Session an jedem Punkt ihrer Historie forken. Der Fork klont die echte Provider-Session, nicht bloß ein Transkript, der Agent erinnert sich also wirklich an alles bis zu diesem Punkt. Das ist der "Moment mal, was wäre, wenn wir es andersherum gemacht hätten"-Knopf. Ich benutze ihn dauernd. Claude Code lässt dich dasselbe nativ machen, aber nicht so geschmeidig wie bb.

Side Chat. Du kannst eine kurze Nebenunterhaltung abseits des Haupt-Threads führen, ohne ihn zu stören. Claude bemerkt mitten im Lauf ein nicht geschlossenes "Gate" oder einen vergessenen Unterpunkt einer Spec, oder ich muss etwas Angrenzendes nachschlagen, und der Kontext des Haupt-Threads bleibt sauber.

Notizen an Turns. Das ist das eine, das es nicht gab. Also habe ich es gebaut.

Das Plugin

bbs Plugin-API ist keine Plugin-API im üblichen "wir haben sechs Hooks freigelegt"-Sinn. Ein Plugin ist TypeScript, das den Server direkt erweitert: eigene SQLite-Datenbank, HTTP- und RPC-Endpunkte, Hintergrundjobs, Einstellungen, die in der UI gerendert werden, React-Komponenten in der App und ein eigener bb-Subcommand, der wie jeder eingebaute funktioniert. Fast alles, was bb mitliefert, ist so gebaut, und das ist der eigentliche Beweis, dass die API ehrlich ist.

Das Ganze hat fünfzehn, vielleicht zwanzig Minuten gedauert.

Was es tut: mit der Maus über eine beliebige Nachricht in einem Thread fahren, auf "Add note" klicken, und im Seitenpanel öffnet sich ein Notes-Tab mit einem Feld, das bereits an dieser Nachricht verankert ist. Schreiben, mit Cmd+Enter speichern. Nie die Session verlassen, das war die halbe Miete.

Die andere Hälfte ist das, was später zurückkommt. Notizen stehen in der Reihenfolge der Timeline, wer das Panel von oben nach unten liest, geht also die Session der Reihe nach durch. Jede trägt ein Fragment der Nachricht, an der sie hängt, und die Notiz sitzt weiterhin an ihrer eigenen Position in einem Thread, durch den ich scrollen kann. Ich muss den Kontext also nicht beim Festhalten zusammenfassen. Ich zeige einfach darauf und mache weiter, und die Überlegung ist noch da, wenn ich zurückkomme, weil ich die Notiz nie von der Konversation getrennt habe, aus der sie entstanden ist.

Es gibt außerdem einen bb note add-Befehl, ein Skript oder ein Hook kann also eine Markierung setzen.

Was es bewusst nicht tut

Die Notizen erreichen das Modell nie. Sie werden nie in den Kontext injiziert, nie an einen Provider geschickt, sie beeinflussen nie einen Turn. Sie gehören mir.

Der Wert dieser Notizen liegt darin, dass sie mein laufender Kommentar zu dem sind, was der Agent tut. In der Sekunde, in der sie Modell-Input werden, hören sie auf, Beobachtungen zu sein, und werden zu Anweisungen, und ich verliere die eine Stelle im Workflow, an der nur ich denke.

Eine ehrliche Ausnahme: den CLI-Befehl zu registrieren heißt, dass ein Agent entdecken kann, dass es Notizen gibt, und eine schreiben kann. Die Inhalte kommen weiterhin nie zu ihm zurück, aber schreiben kann er. Statt das zu verstecken, werden so erzeugte Notizen mit "via bb note" statt "You" gekennzeichnet, damit ich immer erkenne, welche ich selbst geschrieben habe.

Raue Kanten

Die Notizen werden in einem Seitenpanel gerendert und nicht inline unter der Nachricht, was ich ursprünglich gehofft hatte.

Du kannst nur User- und Assistant-Nachrichten annotieren, keine Tool-Calls und deren Output. Die API typisiert es so. Die CLI ist das Schlupfloch, wenn ich eines brauche.

Und bb steht bei 0.38.0 und bewegt sich schnell. Alles, was ich über seine Plugin-Oberfläche sage, hat ein Haltbarkeitsdatum. Kalkuliere das ein, wenn du etwas baust.

Der Teil, der sich verallgemeinern lässt

Normalerweise heißt es, wenn man ein kleines Feature will: einen Request stellen und warten, falls man überhaupt so weit kommt. Vielleicht kommt es, wahrscheinlich nicht, und so oder so liegt die Entscheidung bei jemandem, dessen Prioritäten nicht deine sind. Das ist niemandes Schuld. Das passiert eben, wenn ein Produkt hunderttausend Leute mit hunderttausend verschiedenen Workflows bedient.

Dieser Handel war früher unvermeidlich, weil das Feature selbst zu bauen mehr gekostet hat, als ohne es zu leben. Das ist der Teil, der sich ändert. Die Kosten von "bau es einfach" sind weit genug gefallen, dass bei einem wirklich kleinen Feature mit überproportionalem Nutzen inzwischen das Warten die teure Option ist.

Womit es zu einer Entscheidung wird. Und die Leute, die weiter auf den Feature-Request warten, werden sich zunehmend dafür entscheiden zu warten.

Wenn du den Nervenkitzel behalten willst, deine Agenten auszureizen, dann besorg dir Werkzeuge, die zu deiner Arbeitsweise passen.


Ich habe das Session-Notes-Plugin geschrieben. bb habe ich nicht geschrieben, und ich bin nicht mit dem Projekt verbunden. bb ist MIT-lizenziert und kostenlos, unter getbb.app. Das Plugin ist ebenfalls MIT, unter github.com/pablooliva/bb-ide-session-notes-plugin. Versionsstand bei Abfassung: bb 0.38.0, Plugin-SDK 0.4.6.

Powered by Buttondown.