Remove the C++ engine; upstream Vicinae releases are the reference (ADR-0021) - #235
Merged
Merged
Conversation
iced's default scrollbar is a 10px square rail and scroller. Every scrollable now goes through crate::scroll::scrollable, which draws the C++ ViciScrollBar: 6px wide, radius 3, no rail, the text colour faint at rest and stronger under the pointer or while dragging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Every Markdown view (an extension's Detail, the store detail page, the store intros, the created-extension page) built its settings with `markdown::Settings::with_text_size(14, &theme)`, whose `style.font` is `Font::default()` -- the generic sans-serif -- while every other text widget uses `LauncherApp::font()`. cosmic-text maps generic sans-serif to a hard-coded "Open Sans"; where that family is missing (a stock GNOME install) each span goes through its fallback list instead, and bold spans of a variable default family land on whichever family has a static 700 face (DejaVu Sans Bold, Cantarell Bold...), so the page's text was in a different, mixed face from the rest of the launcher. `LauncherApp::markdown_settings` now sets `style.font` to the launcher font (code keeps iced's monospace) and all four views use it; the store viewer's image placeholder uses the same font. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
publish-flatpak.yaml takes the bundle a green Flatpak run on main already built and smoke-tested, exports it as an OCI image to ghcr.io/tuna-os/compass and records it in the remote's index through the org's shared publish-flatpak-index step. It refuses to publish an image without AppStream labels. The metainfo gains a developer, screenshots, branding colours and a first release. The screenshots are rendered through the paint tier by an ignored test, regenerated with `just screenshots`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
… behind the card Closes the last amber parity cell, src/services/window-material Rust ✓ (152 of 152). The maintainer approved an unsafe exception (ADR-0019): - compass-wayland-foreign: a Linux-only crate that does not inherit the workspace's forbid(unsafe_code); it denies unsafe, restates the other lints, and allows it in one function (adopt) with two blocks, Backend::from_foreign_display and ObjectId::from_ptr. Its safe API, bridge(&window), takes both raw-window-handle handles from one window, accepts only Wayland ones, checks the pointer is a wl_surface, refuses a surface that is not a wayland-rs proxy, names the client_system backend so the wrong one does not compile, and keeps one Connection per display for the process's life. - compass_platform::WindowMaterial (the seam), implemented by vicinae::window_material over the bridge and compass_wayland::material::BackgroundEffects, handed to compass_ui::run_resident by the binary. - compass-ui measures the card with a sensor keyed on tint and corner radius and asks through iced::window::run for the card's rounded rectangle while the card is translucent, none when it is not. - BackgroundEffects drops effects of destroyed surfaces before sending, since set_blur_region on one is a protocol error on winit's display. Under the xdg_toplevel presentation only: iced_layershell drops window::run, a declared difference. Tested on headless Sway (the bridge) and an in-process compositor that blurs (the region traffic); real blur on KWin is VM tier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
The README now leads with what Compass is and a measured comparison against the pinned, unmodified Vicinae v0.29.0 AppImage: cold start (96 ms vs 1,746 ms to IPC ready; 0.9 s vs 2.3 s to a populated launcher), keystroke to frame (56 vs 153 ms), idle PSS (218 vs 263 MiB), 46 vs 136 shared objects and 72 MB vs 310 MB of program files. It also says where Compass loses: its fuzzy scorer is 2-3x slower per core, and it runs more threads. - scripts/bench/compare.sh and compare.py (just bench-compare): headless Sway, a private D-Bus bus with no activation, throwaway HOME/XDG, both engines under unshare --net, alternating runs, process trees found by an environment tag. - scripts/bench/fuzzy/cpp_rank.cpp and compass-testkit's fuzzy-throughput bin: the two scorers over the same 10k haystack and queries. - docs/rust-engine/BENCHMARKS.md: method, machine, raw per-run numbers, the SLA benches, and a still-to-measure list. The raw report is archived under benchmarks/2026-09-25-compare. - Install: the TunaOS Flatpak remote (com.vicinae.Vicinae), CI bundle, flatpak-builder, the other packages and cargo. Stale migration-status prose and Vicinae-only instructions are gone; credit to Vicinae is kept. - CONTRIBUTING.md points at Compass's tracker, not Vicinae's; CUTOVER.md no longer quotes 70/158. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
…mand broker, and an overrides manifest Measured first: of the top 300 Raycast store extensions, 153 carry a macOS-only signal (90 AppleScript/JXA, 39 ~/Library paths, 28 `open`, 27 Homebrew prefixes, 0 pbcopy/pbpaste); docs/rust-engine/RAYCAST-LINUX-SHIM.md has the table and scripts/suite1/macos_signals.py reproduces it. - The runtime's shim (extension-manager/src/linux-shim): child_process and fs behind proxies for the extension's require. `open` runs xdg-open, pbcopy/pbpaste use the runtime's clipboard, osascript and other macOS-only programs fail by name (CompassRefusal/ENOTSUP) instead of ENOENT, Homebrew's macOS paths map to Linuxbrew's. process.platform stays linux. - The broker (HostCommand/run, vicinae::host_commands): `brew`, for any extension, runs on the host as the engine's child (flatpak-spawn --host inside the Flatpak) once the person allows it: Allow Once / Always Allow (Ctrl+Enter) / Deny. Grants in $XDG_CONFIG_HOME/compass/ host-command-grants.json, listed and revoked in Script Permissions. The extension's Landlock policy is not widened. IPC v22 for the alert's third answer. The Qt engine refuses the call by name. - The overrides manifest (extensions/raycast-linux-overrides.json): per extension host programs, path and command maps, load-time patches and install redirects, read by the runtime and the engine. Raycast's real Brew bundle renders Show Installed and Search against a Linuxbrew `brew` behind the sandbox; an end-to-end test covers the same path with a fake brew. The runtime gets unit tests (npm test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Clicks on the root search list did nothing: its rows were the only list rows not wrapped in a mouse_area, so a press reached no handler. A click now sends ResultClicked, which selects the row and does what Enter on it does, and hands focus back to the search field. Hover still never moves the selection, as the C++ SelectableDelegate. The window painted a light rectangle behind the card on both the layer surface and the xdg_toplevel: no program style was set, so iced cleared every frame to the theme's background (the card's surface colour). LauncherApp::style clears to transparent and is wired into run, run_resident and run_resident_layer_shell. Tests: Simulator clicks on a root application row (launches that row, not the selected one), on a root command and then a store row (opens the store, then that extension), and a hover that must not select; the paint tier checks the window below the card's shadow is alpha 0 with the app's style, with the theme's base colour as a failing control. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
The Rust side of the Phase 7 cutover (ADR-0012; spec in ADR-0020).
- crates/vicinae is now crates/compass: package, library and binary
`compass`; the helpers are `compass-file-indexer` and
`compass-input-server`, looked for in ../libexec/compass or
../lib/compass.
- Config, data, cache and state live under `compass`, the config file is
`compass/compass.json`, the schema `compass.schema.json` (regenerated), and
the IPC socket is `$XDG_RUNTIME_DIR/compass/ipc.sock`
(`/tmp/compass-$USER` without a runtime dir).
- On `compass serve`, before anything creates a `compass` directory, each
`vicinae` base directory is moved to `compass` and left as a symlink. When
`compass` already exists (the pre-cutover engine kept scripts, grants and
caches there), the entries it lacks are moved in and nothing is
overwritten; `vicinae.json` becomes `compass.json` the same way.
- `COMPASS_*` environment variables, with the `VICINAE_*` spelling read as a
fallback that logs a deprecation once. `VICINAE_API_URL` is
`COMPASS_VICINAE_API_URL`.
- Compass emits `compass://` and accepts `vicinae://` and `raycast://`.
- D-Bus: `org.tunaos.compass.WindowTracker` for KWin, and the shell
extension contract is `org.tunaos.compass.Shell.{Windows,Clipboard}` at
`/org/tunaos/compass/Shell/*`. App id, tray item and icon are
`org.tunaos.compass`; layer-shell namespaces `compass` and `compass-hud`.
- User-facing strings say Compass. Report Bug files against tuna-os/compass;
the Discord builtin and tray entry are now "Compass on GitHub", and the
sponsor entry is labelled as upstream credit.
- The extension runtime is given COMPASS_VERSION/COMMIT and reads the
`VICINAE_*` names only as a fallback; the SDK dev client dials the new
socket and emits compass:// links.
Kept on purpose: @vicinae/api, store.vicinae.* ids and the Vicinae store,
the keyring labels the importer reads, the vicinae-hotkey-v1 protocol, the
@Vicinae script-command scope, the vicinae-dark/-light theme ids and C++
references.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Rename the Flatpak manifest, desktop entries and metainfo to the org.tunaos.compass ID and ship the `compass` binary, with libexec/compass and share/compass layouts, across the Flatpak, AppImage, Arch and Nix outputs. The metainfo <replaces> com.vicinae.Vicinae, the URL handler takes compass:// alongside vicinae://, raycast:// and com.raycast:, and an opt-in compass.service user unit is installed. The GNOME Shell extension becomes compass@tunaos.org with its interfaces under org.tunaos.compass.Shell.*. The config schema moves to compass.schema.json and nix/vicinae.nix to nix/compass.nix. CI workflows, the VM tier, Suite 1/5, tier 2, wlroots and the bench scripts build `-p compass` and run target/*/compass; the benchmarks still launch the pinned upstream Vicinae AppImage under its own name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
…R-0020) The README, CONTRIBUTING and the Rust engine docs use the new app ID, the compass command, the compass crate and the compass config, data, cache, state and runtime directories. The README says an existing ~/.config/vicinae is moved on first start instead of saying the old names are kept. ADR-0020 records the rebrand: the new names, what keeps the vicinae name and why (@vicinae/api, vicinae:// deeplinks, the Vicinae Store, VICINAE_* fallbacks, upstream credit, the C++ tree), the directory migration, and why no Flatpak data migration is needed. It supersedes ADR-0012's compatibility list. The TypeScript READMEs and package metadata describe Compass. The @vicinae/api module name stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
The Vicinae store's Linuxbrew extension now reaches brew through the consent-gated broker, so a headless run sees its 'Allow Linuxbrew to run brew?' prompt and nothing answers it. Record that as its own verdict, like needs-sign-in for OAuth, rather than as an empty frame, and expect it in the ledger. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
…DR-0021)
The parity ledger reads 152/152 and the benchmarks already measure the
pinned upstream v0.29.0 AppImage, so the in-tree C++/Qt engine goes.
Removed: src/{server,cli,lib,data-control-server,file-indexer,snippet,
wayland-protocols,browser-extension}, CMake (top level, cmake/,
src/typescript's), clang-format/tidy/clangd/qmlformat configs, vendor/
except fuzzy-trigram, nix/vicinae.nix and default.nix, the C++ build
scripts (scripts/runners, macOS/Windows packaging scripts), the C++
Makefile targets and the C++ CI workflows (build-linux, build-macos,
build-windows, build-appimage, build-appimage-image, macos-dmg,
cpp-on-target) and release.yml's C++ jobs. The HostCommand C++ stub goes
with src/server.
Moved what Rust reads: the glyph table to crates/compass-core/glyph, the
builtin icons to extra/builtin-icons (names now from @vicinae/api's Icon
enum), the migrations into compass-db and compass-clipboard, the
script-command corpus to a compass-core fixture, the Qt catalogues to
extra/translations/qt, and upstream's fuzzy and crypto sources plus the
probes to scripts/bench so the differentials run against upstream.
figura is ported to Rust (crates/compass-figura, TypeScript only,
byte-identical output); the extension runtime's bindings are committed
and a test keeps them current, so building the runtime needs only npm.
Tests that parsed C++ sources pin upstream's values or are dropped where
Rust tests already pin them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
- AGENTS.md rewritten for the Rust workspace: separation between compass-ui and the logic crates, the workspace lints, the platform seam test, the test ladder, cargo fmt/clippy/alejandra, and i18n as it stands (fluent-rs decided, catalogues not yet converted). - nix/: programs.compass (Home Manager) and programs.compass.input-server (NixOS), with upstream's programs.vicinae names renamed or removed. The soulver/numen, browser-host, launchd and settingOverrides options go: the calculator is fend-core and the engine is Linux only. - extra/: delete the C++ build's macOS, Windows, desktop, systemd, modules-load.d and config.jsonc files; nothing in the Rust build reads them. - PARITY.md's C++ deleted column is green everywhere; the scorer's docstring says why it still reads 152/152. - CONTRIBUTING.md, packaging/README.md, manifest.yaml, .envrc, .gitignore and helper comments lose their C++-era references. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
The C++ removal's rewrite of extension-runtime.nix kept the pre-rename share/vicinae path, so the compass derivation found no runtime bundle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
hanthor
pushed a commit
that referenced
this pull request
Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Rust engine covers 152 of 152 parity rows, so the legacy C++/Qt engine is removed. Benchmarks and differential tests now use the pinned upstream Vicinae release, which scripts/bench already downloads and SHA-checks.
Removed (about 1,400 files, about 20 MiB)
src/server,src/lib,src/cli,src/data-control-server,src/file-indexer,src/snippetandsrc/wayland-protocols. The Rust crate already has identical copies of the protocol XML.src/browser-extension. Its native host only spoke to the C++ daemon, and browser control was left out of the port (ADR-0008).CMakeLists.txt, presets,cmake/), the clang-format/clang-tidy/clangd/qmlformat configs, andvendor/exceptfuzzy-trigram, whichcompass-sqlcipher-syscompiles.build-linux/macos/windows/appimageworkflows, plusbuild-appimage-image,macos-dmgandcpp-on-target.release.yml, which now resolves the tag, publishes to npm and cuts a GitHub release.nix/vicinae.nix. The macOS and Windows bundle files and the old vicinae desktop, service, icon and config files inextra/.Moved
crates/compass-core/glyph/extra/builtin-icons/crates/compass-db/migrations/vicinae/andcrates/compass-clipboard/migrations/crates/compass-core/tests/fixtures/extra/translations/qt/. All 7,347 messages are still accounted for byts-to-ftl.py --check.scripts/bench/upstream/. They are checked byte-for-byte against v0.29.0 and still drive the scorer and crypto differentials inrust.yaml.Ported
figura, the IDL generator, is now
crates/compass-figura. Its output is byte-identical to the C++ figura for all six.figfiles, and the extension runtime's bindings are committed, with a staleness test. Building the runtime now needs only npm, so Flatpak, Nix, Arch and CI no longer need g++ or CMake.Cleanup
unsafeexceptions, the seam test, the test ladder, fmt/clippy/Biome/alejandra, and the i18n rules.programs.compass(with a user service andcompass.json) and NixOSprograms.compass.input-server.programs.vicinae.*stay as renamed-option aliases; soulver, numen and browser are removed with a reason..gitignoreand.envrc: C++-era text is gone.Verification
Local:
cargo fmt --check, workspace clippy-D warningsandcargo test --workspaceall pass (4,669 passed, 0 failed).parity-score.pyreports 152/152. The runtime build andnpm testpass, and every workflow file parses. The nix modules pass alejandra, but nix was not evaluated here; the Nix package CI job covers that.🤖 Generated with Claude Code
https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Generated by Claude Code