From dfcfeed8b14951ca73f0de3e1b0d4d48fe12cc65 Mon Sep 17 00:00:00 2001 From: Martijn Jansen Date: Mon, 15 Jun 2026 19:03:33 +0200 Subject: [PATCH] file T-440: build + vendor tree-sitter.dll for Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the Windows-DLL slice out of T-25 (cross-OS libtree-sitter build). The FFI loader already resolves tree-sitter.dll on Windows, but no Windows binary is vendored — only the Linux .so — so tree-sitter highlighting silently falls back to plain text on Windows. T-440 is the narrow task to build and vendor that DLL now; CI reproducibility and the macOS .dylib stay on the T-25 umbrella. Co-Authored-By: Claude --- .pql/changelog/ticket_idmap/2026-06.sql | 1 + .pql/changelog/tickets/2026-06.sql | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/.pql/changelog/ticket_idmap/2026-06.sql b/.pql/changelog/ticket_idmap/2026-06.sql index d8a29903..caeabaa9 100644 --- a/.pql/changelog/ticket_idmap/2026-06.sql +++ b/.pql/changelog/ticket_idmap/2026-06.sql @@ -264,3 +264,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCNYXXH5AAHZR7WV0550J3RC', 'T-437', '2026-06-15 11:12:36', '2026-06-15 11:12:36', NULL, '74dd08c8c42f556959746ee1a47561e6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQ8HB61N3TWVJ8YSMHH2TJ4', 'T-438', '2026-06-15 14:14:23', '2026-06-15 14:14:23', NULL, 'fa072ae8dd819784440bb44b5fe689d8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQHWQ40AY6SNVRJ86YWA0J8', 'T-439', '2026-06-15 14:55:15', '2026-06-15 14:55:15', NULL, '2427484ebb324d731cb8e099a2ad04ab', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); +INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCRERT7X5WMZSGKQCA6T0VB4', 'T-440', '2026-06-15 17:01:25', '2026-06-15 17:01:25', NULL, 'b8e152bf87ec8d81d1bddeb023f37883', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index 155ea23b..1eb15086 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -6254,3 +6254,16 @@ So T-347 fixed the *toolchain/pql* path on Linux, but the `env.dart` copy (git, **Acceptance.** Desktop-launched clide on Linux + macOS resolves the same PATH the user''s login shell has; pql/git/claude and PTY children all find user-installed tools; the three divergent expanders are unified into one; graceful fallback when the shell probe fails or times out; covered by a test for the resolver + the fallback. **Related:** T-347 (done — fixed the Linux toolchain/pql path, but only `toolchain_paths.dart`), T-215 (CLIDE_SOCK/CLIDE_WORKSPACE + clide on the child PATH), T-211/T-212 (clide-on-PATH install), D-59 (bundled git) / D-92 (bundled pql) — bundling covers git/pql specifically, but not the general "user''s installed tools" PATH this addresses.', 'in_progress', 'high', NULL, NULL, NULL, '2026-06-15 14:55:15', '2026-06-15 15:32:16', NULL, 'cd231fbbec9b6faa4659286c24893d30', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCRERT7X5WMZSGKQCA6T0VB4', 'task', '06FB0TNQM4W194B2421P2SF83R', 'Build + vendor tree-sitter.dll for Windows x64', 'Split from T-25 (cross-OS libtree-sitter build). Narrow, immediately-useful slice: get tree-sitter syntax highlighting working on Windows now, ahead of the full reproducible-CI cross-compile story. + +**Current state (verified 2026-06-15):** The FFI loader already selects ''tree-sitter.dll'' on Windows (lib/kernel/src/syntax/tree_sitter_ffi.dart:261), but NO Windows binary is vendored — git ls-files shows the only tree-sitter artifact in the repo is native/linux-x64/libtree-sitter.so. native/windows-x64/ contains only clide.exe (the CLI client). Result: on Windows the loader hits the null / lastOpenError path and tree-sitter highlighting silently does not load (plain-text fallback). Same gap exists for macOS .dylib, tracked separately under T-25. + +**Scope:** build tree-sitter v0.26.8 (tag v0.26.8, commit cd5b087cd9f45ca6d93ab1954f6b7c8534f324d2 — same pin as the Linux build) for x86_64-windows with TREE_SITTER_FEATURE_WASM=ON and wasmtime statically linked, producing tree-sitter.dll. Vendor it at native/windows-x64/tree-sitter.dll, alongside a native/windows-x64/BUILD.md build record mirroring native/linux-x64/BUILD.md (source repo, version, commit, build command, MSVC/toolchain, wasmtime version + static-link note, exports, SHA-256, binary size). Add/extend the assets/licenses.yaml entry so the Windows artifact + wasmtime are documented (D-42). Ensure the Windows Flutter bundle places the DLL where DynamicLibrary.open finds it (bundle dir / next to clide.exe — loader already probes ''$exe'' and ''$exe/lib''). + +**Acceptance:** +- native/windows-x64/tree-sitter.dll committed; SHA-256 recorded in native/windows-x64/BUILD.md. +- On Windows, TreeSitterLib.init() succeeds (lastOpenError == null) and a code file renders with tree-sitter highlighting (not plain-text fallback). +- licenses.yaml documents the Windows tree-sitter artifact + statically-linked wasmtime. +- DLL is included in the make build-windows / Windows bundle output and loads from the bundled path. + +**Out of scope:** CI reproducibility, macOS .dylib cross-compile, and the wasmtime NOTICE-file vendoring — those stay on the T-25 umbrella. This ticket is the hand-built Windows DLL to unblock highlighting locally now. Once T-25''s CI cross-compile lands, the Windows target folds into it.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-15 17:01:25', '2026-06-15 17:01:25', NULL, '9965c3d1b894e3af420f2e625b46efc4', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);