Contextify kommt auf Windows: Ein Swift-Kern, drei Plattformen

Contextify erfasst deine lokalen Claude Code- und Codex-Sitzungen in einem lokalen SQLite/FTS-Index, damit du deinen KI-Programmierverlauf durchsuchen und lesen kannst. Es funktioniert rein lokal. Wahlweise kannst du gehostete oder selbst gehostete Cloud-Synchronisierung nutzen, um den Verlauf auf einem anderen Rechner zu lesen.

Einige Leute haben nach einem Windows-Client gefragt, weil ihre selbst gehosteten Umgebungen Mac-, Linux- und Windows-Rechner enthalten, die alle Transkripte von KI-CLIs erzeugen, manchmal ohne grafische Oberfläche. Contextify begann als macOS-App. Version 1.8.0 bringt es auf Windows (x64 und ARM64) und erweitert die Linux-CLI. Auf Windows besteht es aus einem Hintergrundagenten und einer CLI, bisher ohne Oberfläche zum Durchsehen des Verlaufs.

Dafür war viel interessante Arbeit nötig, einschließlich eines gemeinsamen Swift-Kerns. Und zwar so, dass sich alles weiterhin genauso leicht aktualisieren lässt wie vor dieser Version. Hier sind die schwierigeren Teile.

Der gemeinsame Swift-Kern

Parser, Schema und Migrationen, SQLite + GRDB + FTS5, Abfragen/Export und Cloud-Synchronisierung bilden eine einzige Swift-Codebasis, die sich macOS-App, Linux-CLI und Windows-Client teilen. Auf Windows läuft dieser Kern als dauerhaft aktive Engine (contextify-windows-engine.exe). Die .NET/Avalonia-Tray-App spricht einfach über zeilengetrenntes JSON auf stdio mit ihr.

Ursprünglich habe ich es anders gebaut. Der erste Windows-Client begann tatsächlich als vollständige Neuimplementierung in C# mit eigenem Parser, SQLite und Synchronisierung. Das war ein Fehler. Mir wurde klar, dass die Implementierungen stark auseinanderlaufen würden. Da Linux und macOS bereits gemeinsamen Swift-Code nutzten, war es viel sinnvoller, Windows auch einzubeziehen.

Ich habe mit einem Spike nachgewiesen, dass sich mit Swift 6.3.3 + GRDB + einer mitgelieferten SQLite-Version unter Windows 11 ARM64 ein FTS5-Schreib-/Suchdurchlauf durchführen lässt, und danach im Grunde neu angefangen. Das war eine wertvolle Änderung und brachte mich auf den Weg zu einem richtigen gemeinsamen Kern. (Mehr zu ARM64 und x64 später.)

Unterwegs Lücken finden

Eine Sache verlängerte die Entwicklung: Der Fokus auf den Windows-Build und dessen Prüfung deckte Verhaltensunterschiede zwischen den macOS- und Linux-Apps auf, die ich übersehen hatte. Nutzer hatten sie noch nicht gemeldet. Aber ich sah, wie der Agent beim Ausführen der Contextify-CLI auf Linux auf unerwartete Fehler stieß, und dachte nur: Häää?

Irgendwann ergänzte ich also den Swift-Kern und übertrug die Änderungen zurück in die Linux-App. Dabei kramte ich Tickets hervor, die ich genau für diese Lücken angelegt und im Backlog aus den Augen verloren hatte.

Windows x64 auf einem Mac bauen (ohne x64-Rechner)

Zu Beginn war mir nicht klar, dass eine x64-Windows-Laufzeitumgebung überhaupt nicht mit dem vergleichbar ist, was Rosetta beim Laden von x64-Anwendungen auf macOS ermöglicht. Ich lernte, dass das Kompilieren für x64 unter Emulation auf Apple Silicon schlicht unpraktisch ist. Die Build-Zeiten sind viel zu lang für Entwicklungsiterationen.

Ich habe Preise für echte Build-Rechner verglichen, konnte mich aber nicht zum Kauf durchringen, weil Builds und QA nur stoßweise anfallen würden. Stattdessen habe ich DevOps-Werkzeuge gebaut, um virtuelle Maschinen in Azure für QA und Builds bereitzustellen und ihre Ressourcenzuweisung anschließend wieder aufzuheben.

Bevor ich zu Azure wechselte, nutzte ich, was gerade verfügbar war: von GitHub gehostete Runner. Aber Kaltstarts und Preis-Leistungs-Verhältnis taugten nichts. Hoch- und Herunterfahren dauerten über 40 Minuten. Bei den Azure-x64-Rechnern, die ich nutze, wird die Ressourcenzuweisung im Ruhezustand aufgehoben. Sie werden also nur während des tatsächlichen Kompilierens berechnet. Ein vollständiger Kaltstartzyklus einschließlich Hoch- und Herunterfahren dauert etwa 13 Minuten.

Weg von GitHubs Runnern

GitHub hatte in dieser Zeit außerdem zwei schwere Ausfälle, die den Weg zur Windows-Veröffentlichung noch länger machten. Ich habe meine CI vollständig von gehosteten Runnern weg verlagert. Alles außer x64 wird jetzt auf meiner eigenen Hardware gebaut und signiert: einem Mac mini M4 in der Basisausstattung (bald durch einen M5 Pro ersetzt) und meinem MacBook Air M5. Die einzige Ausnahme ist x64 mit den oben beschriebenen Azure-Rechnern, deren Ressourcenzuweisung im Ruhezustand aufgehoben wird.

Windows-Versionen signieren

Eine unsignierte Windows-App konfrontiert Nutzer mit Warnungen, sie nicht auszuführen. Contextify muss zumindest von Windows 11 als vertrauenswürdig eingestuft werden.

Microsofts empfohlener günstiger Azure-Signierdienst war Zeitverschwendung. Er verlangt eine Identitätsprüfung durch einen Drittanbieter, die meine Identität nicht akzeptierte und immer wieder ohne Begründung und ohne Fehlercode scheiterte. Die Dokumentation von Microsoft wird von irgendeinem KI-Ding betrieben, das nicht funktioniert. Der einzige kostenlose Weg, Microsoft zu erreichen, führt über die Supportforen. Dort habe ich noch immer keine Antwort. Leute, die für Support bezahlt haben, haben ähnliche Probleme gemeldet, ebenfalls ohne Antwort.

Die nächstbeste Option schien ein SSL.com-Zertifikat mit Signierung über deren Cloud zu sein. Ich habe lange über einen eigenen YubiKey nachgedacht, am Ende aber auch für ihren Cloud-Schlüssel bezahlt. Als ich mich einfach darauf eingelassen und das Geld gezahlt hatte, war die Bestätigung meiner Identität ~trivial.

Die Website von SSL.com ist absurd schlecht. Neben Design und Navigation gibt es Oberflächen mit unvollständigen Informationen, für die der Supportbot offensichtlich schon eine vorgefertigte Behelfslösung parat hat. Statt die Website zu reparieren, hinterlegen sie den Umweg im Supportchat. SSL.com erreicht neue Höhen bei Produktpflege und Kontrolle der Supportkosten.

Der Witz ist, dass man direkt nach der Anmeldung als Erstes erfährt, wie man sich registriert, um Affiliate-Links zu erstellen und ihre Produkte weiterzuverkaufen.

Microsoft sollte entweder den eigenen Signierprozess im Griff haben oder bei seinen Partnern bessere Nutzererfahrungen durchsetzen.

Ein interessanter Swift-Bug

Swift auf Windows gibt es wirklich (!), aber die Concurrency-Laufzeit ist dort jünger als auf dem Mac.

Die dauerhaft aktive Engine stürzte auf Windows x64 mit einer Zugriffsverletzung (0xC0000005) in swift_task_localValuePush ab, bevor sie ein einziges Argument geparst hatte. Identischer task-lokaler Code lief auf macOS problemlos und stürzte auf Windows x64 einfach hart ab: keine Fehlermeldung, direkt eine Zugriffsverletzung. In meinem Fall lag es daran, dass der Engine-Zustand durch verschachtelte @TaskLocal-Werte weitergereicht wurde. Ich habe das behoben, indem ich einen expliziten Sendable-Kontext entlang der Aufrufkette weitergab.

Jedenfalls habe ich gelernt, dass Zugriffsverletzungen mit asynchronem Swift auf Windows gar nicht so ungewöhnlich sind, selbst wenn sie auf Darwin nie auftreten.

Die App selbst

Die Installation erfolgt pro Nutzer ohne erhöhte Rechte: keine Administratorrechte, kein Windows-Dienst, kein MSI. Updates installiert die App selbst. Ich habe einen PR für die Aufnahme in winget eingereicht. Bis dahin gibt es das signierte Installationsprogramm auf der Website oder auf GitHub.

Die App arbeitet zuerst lokal: Nur die Engine schreibt in die Datenbank. Cloud-Synchronisierung ist erst nach der Anmeldung verfügbar und muss ausdrücklich aktiviert werden. Am meisten interessiert mich Feedback dazu, ob und wann Indexierung oder Synchronisierung auf echten Windows-Systemen ausfallen, sowie zur allgemeinen Bedienung der App.

Contextify für Windows

Kostenlos ausprobieren. Deine Daten bleiben auf deinem Rechner.

Herunterladen für Windows