Serie: Vibe Coding - Teil 3: UniTree

  Ralf Hersel   Lesezeit: 5 Minuten Auf Mastodon ansehen

In dieser Serie versuche ich, eine alte Anwendung mittels Vibe-Coding in die Neuzeit zu retten. Das erfolgt im Rahmen einer kritischen Einordnung.

serie: vibe coding - teil 3: unitree

Inhaltsverzeichnis

Teil 1: Motivation
Teil 2: Treenotes
Teil 3: UniTree (das ist dieser Artikel)

Das richtige Werkzeug

Nun ja, mein Versuch in Teil 2, eine einfache Version von UniTree (Treenotes) zu erstellen, war nicht von Erfolg gekrönt. Ein Wald-und-Wiesen-Chatbot, wie Microsoft Copilot eignet sich nicht für die Migration eines fast 20 Jahre alten Quellcodes. In den Kommentaren wurde empfohlen, Opencode mit dem kostenlosen Space-Bunny-Modell zu verwenden. Das habe ich gemacht.

Opencode habe ich in der Version 1.19 als AppImage installiert. Nach dem Start kann man unten das Modell auswählen (Space-Bunny-Free in der High-Variante). Danach erläutert man, was man machen möchte. Hier seht ihr Auszüge der Prompts und Rückmeldungen, bzw. Rückfragen.

Fragen und Antworten

So ging es los:

Wenn ich dir alten Python-Code gebe, kannst du den migrieren?

Ja. Schick mir den Code (oder den Pfad dazu) – ich sehe mir an, welche Python-Version er braucht, und migriere ihn auf aktuelles Python (Typing, match, pathlib, kein datetime.utcnow mehr, usw.). Sag mir ggf. noch das Ziel (Version, Frameworks).

Die Anwendung heisst UniTree. Sie ist in Python 2 und Gtk 2 geschrieben. Das Ziel ist es, daraus eine Python 3 Anwendung zu machen, die Gtk 4 und libadwaita verwendet. Hier sind zwei Links, die UniTree näher beschreiben:

https://launchpad.net/unitree

https://www.rum3ber.ch/index.php/projekte/unitree

Lies dir die Informationen durch und sage, ob du weitere Informationen benötigst. Den Source-Code gebe ich dir im nächsten Schritt.

Was ich für die Planung noch brauche (aber erst mit dem Code beantwortbar bzw. hilfreich):

  1. Quellcode selbst – die entscheidende Info. Struktur, Dateigrößen, gespeichertes Datenformat (XML? eigene Dateiendung?).
  2. Zieldetails, die ich nicht raten sollte: Ziel-Python (3.12+?), Paketierung (Flatpak? PyInstaller? setuptools), soll die alte .unitree-Dateiformat-Kompatibilität 1:1 erhalten bleiben oder darf das Format mitversioniert werden?
  3. Umfang der UI-Neuheit – strikt 1:1-Portierung der Bedienung (Menüs, Shortcuts, Tabs) oder darf die Oberfläche modernisiert/umgebaut werden (Adwaita-typisch: HeaderBar, SplitView, Toast-Dialoge, Suchbar statt Menüeintrag)?
  4. Erststart-Verhalten: das Programm startet laut Homepage mit der Hilfe-Datei – soll das bleiben?
    Schick mir einfach den Code, dann schätze ich den Aufwand und lege los.

1. Der Quellcode ist im Anhang.
2. Ziel ist Python 3.14, Gtk 4, Libadwaita. Das Speicherformat soll geändert werden.
3. Die UI soll moderner sein.
4. Das Programm soll nicht mit der Hilfe-Datei starten.

Was ihr oben seht, sind wesentliche Elemente des Dialogs. Tatsächlich befinden sich dazwischen seitenlange Analysen und Tätigkeitsmeldungen. Die Fragestunde geht weiter (konnte ich nicht kopieren, daher als Screenshot):

Dann vergehen ca. 70 Minuten, in denen Opencode mit dem Space-Bunny-Modell mit der Migration beschäftigt ist. Währenddessen kann man mitlesen, was das Modell gerade anstellt. Opencode handelt agentisch, weshalb man bestimmte Rechte einräumen muss.

Interessant fand ich, dass Opencode zwischendurch die Anwendung startet, Screenshots erstellt und UI-Tests durchführt. So erhält man bereits während der Generierung einen ersten Eindruck von der fertigen Applikation.

Das Ergebnis

Opencode liefert nach der Generierung einen Bericht ab:

Die neue Anwendung liegt in /home/ralf/dev/unitree4 (5.166 Zeilen Python, 4701 davon ohne Tests).

  • python3 -m unitree                                       # leeres Dokument
  • python3 -m unitree samples/demo.utrx     # Demodokument
  • python3 -m unitree --help

Kern (unitree/core/, ohne GTK – headless testbar)

  • model.py — Node/Attribute, die Semantik ist jetzt explizit kodiert: ROOT→KID→INSTANZ→KID… als Tabelle CHILD_TYPES. Links werden nur noch einmal gespeichert, Rück-Links werden berechnet → der inkonsistente Zustand aus 0.89 ist strukturell unmöglich.
  • document.py – Undo als vollständige Zustandskopien (inkl. Links, per UID-Remapping), Journal.
  • storage.py – JSON .utrx (lesbar, diffbar), dazu TXT- und XML-Export.
  • operations.py – Drop-/Verschieberegeln inkl. Zyklenschutz, Tiefenlimit, Merge-Pflicht; rows() erzeugt die flache Zeilenliste mit Rolle own/link/backlink.
  • search.py – Volltextsuche, Link-Suche, Wortindex für Autoverlinkung.
    Oberfläche (unitree/ui/) – HeaderBar statt Menü/Toolbar, OverlaySplitView, Toast/AlertDialog, ColumnView für die Instanztabelle, Adw.PreferencesGroup für die Attributeditoren, GtkSourceView5 (Undo/Redo, Auto-Indent, Auto-Bullet), ListView + Draw&Drop mit allen 12 Validierungsregeln, Kontextmenü, F3/F4, PDF-Export mit Pango + pydyf.

Verifiziert: 42 Unit-Tests, 27 GUI-Smoke-Checks (läuft real auf deinem Display), ruff sauber, Screenshots in DE und EN.

Drei echte Fehler, die die Tests gefunden haben: copy_tree hängte komplett außerhalb der Klasse (Methoden journal_entry/find_category waren tot), der i18n-Cache ließ Englisch die deutsche Sprache überschreiben, und der Drag-Source-Code war nie in _on_setup gelandet – Drag'n'Drop hätte gar nicht funktioniert.

Was du wissen solltest

  • .utr (Pickle) wird nicht gelesen – wie entschieden. unitreehelp.utr ist damit inhaltlich weg; die App startet mit leerem Dokument (nicht mit der Hilfedatei).
  • Drucken entfällt, dafür PDF-Export.
  • Drag'n'Drop habe ich programmatisch über die Regeln und die Controller verdrahtet geprüft, nicht mit einer echten Maus – das solltest du einmal von Hand testen.
  • Ich habe pytest und ruff nach ~/.local installiert (--break-system-packages), weil die Sandbox kein venv anlegen konnte.

Läuft es?

Ja, es läuft, enthält aber viele Fehler und Funktionen, die nicht oder falsch implementiert sind. Im Titelbild seht ihr ein Beispiel der Instanzansicht und hier ist die Kategorieansicht:

Spannend finde ich, dass die KI das Konzept der Anwendung "verstanden" hat. Damit meine ich die unterschiedlichen Bedeutungen der Knoten im Baum. Die Kategorieansicht zeigt die untergeordneten Instanzen mit deren Datenfeldern. Für jede Kategorie können eigene Felder definiert werden:

Die Felder stehen auf den Instanzknoten zur Verfügung und können mit Daten befüllt werden.

Nein, es läuft nicht!

Die migrierte Anwendung ist sehr fehlerhaft:

  • Die Daten werden nicht gespeichert. Das verlangte Autosave macht nichts.
  • Die Navigation im Baum, entspricht nicht dem, was ein Mensch sich ausgedacht hat.
  • Das Hinzufügen von neuen Feldern für Kategorien klappt nur manchmal.
  • Funktionen aus dem Kontextmenü gehen nicht, wohl aber aus dem Dreipunkt-Menü.
  • Die Suche läuft gar nicht.
  • und so weiter, und so fort

Man merkt dieser Neuimplementierung deutlich an, dass dabei kein menschlicher Entwickler seine Hände im Spiel hatte. Alles wirkt seltsam künstlich und unmenschlich.

Vermutlich habe ich dieses Experiment zu früh abgebrochen. Ich habe keinen Aufwand in das Nach-Prompten gesteckt. In ein paar Stunden hätte ich wahrscheinlich die Fehler beheben können. Falls ich demnächst etwas Zeit dafür finde, werde ich es versuchen. Das geht, weil Opencode den Kontext behält.

Bei dieser Übung wurden 330'000 Token verbraucht, was mir egal ist, weil ich Space-Bunny-Free verwendet habe.

Titelbild: selbst

Quellen:

https://opencode.ai/de

https://spacebunnymodel.com/

Tags

Vibe-Coding, vibe, Vibe Code, Unitree, KI, Opencode

Es wurden noch keine Kommentare verfasst, sei der erste!