Rebrand to Compass (org.tunaos.compass); Raycast extensions on Linux; clickable rows and a transparent window - #234
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
hanthor
pushed a commit
that referenced
this pull request
Sep 25, 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.
Three pieces of work, tested together. A full
cargo test --workspaceon this exact tree passes: 4,678 passed, 0 failed. fmt and workspace clippy-D warningsare clean.1. Rebrand to Compass (ADR-0020, the Phase 7 cutover)
New names
com.vicinae.Vicinaeorg.tunaos.compass(metainfo<replaces>the old ID)vicinaecompass(crates/compass)compass-file-indexer,compass-input-server~/.config/vicinae/vicinae.json~/.config/compass/compass.json…/vicinae…/compass$XDG_RUNTIME_DIR/compass/ipc.sockVICINAE_*COMPASS_*(the old names are still read, with a one-time deprecation warning)vicinae://compass://(vicinae://,raycast://andcom.raycast://are still accepted)org.tunaos.compass.WindowTracker; Shell contractorg.tunaos.compass.Shell.{Windows,Clipboard}at/org/tunaos/compass/Shell/*compass@tunaos.orgcompass.servicecompass,compass-hudMigration. On
compass serve, the engine movesvicinaeintocompassfor the config, data, cache and state directories, and leaves a relativevicinae → compasssymlink so a rollback still works.compassdirectory already exists (pre-cutover builds made some), the engine moves in only the entries it lacks and never overwrites. When a name exists on both sides, it keeps a realvicinaedirectory and logs a warning.vicinae.jsonbecomescompass.jsonthe same way.Builtins
What keeps the name
vicinae, and why@vicinae/api: third-party extensions import it.store.vicinae.*IDs: an upstream third-party service.vicinae-hotkey-v1protocol.Packaging. The manifest, desktop and metainfo files, schema, nix, Arch, AppImage, workflows (including publish), VM tier, suites and benches are all renamed. The benches still launch the pinned upstream AppImage under its own name.
2. Raycast extensions on Linux
openbecomesxdg-open, andpbcopy/pbpasteuse the clipboard.host-command-grants.json, and Script Permissions lists and revokes them.docs/rust-engine/RAYCAST-LINUX-SHIM.md.3. Two UI bugs
mouse_area. A single click now selects and activates a row, the same as Enter, and focus returns to the search field. Hovering doesn't move the selection, as in the C++. Simulator tests click an unselected row.LauncherApp::style()now clears to transparent in all three entry points, and the HUD is fixed too. A new paint-tier test asserts alpha 0 outside the card's shadow, on wgpu and tiny-skia. The fix was also checked by hand on headless Sway in both the layer-shell and xdg_toplevel presentations.Removing the C++ tree follows in its own PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UtGVEzDmYTdpsuEQErmmLn
Generated by Claude Code