desktopEntryMatchesApp normalized haystack values without dropping empty
ones, so a .desktop entry with no ASCII letters or digits in Name, id,
file name, or Exec (e.g. Name=抖音) normalized to "" and
needle.includes("") matched every requested app — hijacking the
installed-apps list and Open In launch specs. Empty normalized haystack
values are now filtered, matching the existing needles handling.
discovered-apps.json gains a version field (INSTALLED_APPS_CACHE_VERSION
= 2); caches written before the fix are treated as stale and refresh
through the existing TTL-expiry path instead of serving the poisoned
list for the rest of the 24h TTL.
* chore: remove verified dead declarations
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* chore: narrow unused internal exports
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* chore: remove newly exposed dead helpers
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* chore: remove unused deep-link serializer
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* test: drop two tests that assert on copies of the code
mainLayoutMobileSidebarMount read MainLayout.tsx and SessionSidebar.tsx as
strings and asserted on source substrings down to exact indentation, so it
failed on formatting rather than behaviour. useProjectSessionSelection.test
reimplemented the hook's visitNodes logic inside the test file and asserted
against that copy, so it could not observe the hook at all.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* test: repair sync suites that had rotted while unrunnable
No runner executed packages/ui, so these drifted from the source unnoticed:
two imported helpers that are no longer exported, one directory-store stub
predated the session field routeMessage reads, and the WebSocket fake missed
the mandatory url-token mint plus the close event the socket wrapper reads.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* test: stop the web suite failing on timeouts and a hand-copied mock
The Git suites drive a real git binary, so the 5s default made a valid suite
fail differently per run. The gitApiHttp mock listed ~70 export names by hand
and fell behind the source; it now derives every stub from the real module,
which the added shared-UI aliases make resolvable.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* test: run every suite from one command and in CI
packages/ui (232 files) and packages/vscode (22) had no test script at all, CI
ran neither, and 9 vscode files could never run because Node cannot resolve
their extensionless TypeScript imports. Three electron files sat outside every
script list, one of them importing vitest, which that package does not depend
on. A runner gives each file its own process, since these suites keep
module-level singletons and fail by load order when sharing one.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* chore: delete a superseded repro harness and a completed plan
The issue-2638 harness needed lsof, overrode process.platform and spawned real
servers, and nothing referenced it; event-stream/rebind.test.js now covers the
same hub-pinned-to-the-old-port behaviour. The pairing v2 plan described relay
and the pairing UI as out of scope, both of which shipped.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* docs: point at the theme tools and record the github barrel invariant
convert-vscode-theme and harmonize-theme were referenced nowhere, so the
theme-authoring reference now names them. The github barrel is loaded through
await import('./index.js') and destructured per route, which no static report
can see; documenting that is what stops the next cleanup from deleting it.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* test: repair merge drift in bridge and route-registry mocks
upstream/main gained upsertProviderConfig on bridge-system-runtime and a
PATCH scheduled-task route after this branch forked. Their test doubles
were never updated to match:
- bridge-system-runtime.test.js: add upsertProviderConfig to the
opencodeConfig mock so the import resolves.
- sse-routes.test.js: add app.patch to the route registry stub.
---------
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
desktopEntryMatchesApp used a loose substring match that accepted any
desktop entry whose Exec line mentioned a terminal launcher. A non-
terminal app launched via xdg-terminal-exec (e.g. a TUI helper) was
mis-attributed to the generic 'terminal' appId, so 'Open in Terminal'
launched the helper script and the picker showed the helper's icon.
For appId === 'terminal' only, require Categories=TerminalEmulator;
ghostty/iterm2 keep name-based matching. The xdg-terminal-exec /
gnome-terminal / konsole / xfce4-terminal / x-terminal-emulator fallback
chain is unchanged, so non-conformant custom terminal entries still
launch. Adds a shared isTerminalEmulatorEntry predicate used by both
buildLinuxOpenSpecs (launch) and buildLinuxInstalledApps (icon).
Smoke test gains a generic helper-app fixture (non-terminal app whose
Exec uses xdg-terminal-exec) plus a TerminalEmulator entry, with
assertions that the helper script is never launched and the terminal
emulator's icon resolves instead of the helper's. Two byte-distinct
PNGs keep the icon assertion a real discriminator.
Resize Linux tray icons so StatusNotifier hosts show them, add Show/Hide/Close
context-menu actions, and resolve FreeDesktop theme icons for Open-in apps
(including the default file manager) instead of skipping Linux icon fetch.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* feat(electron): add Linux AppImage releases
* ci: cache Linux OpenCode CLI artifacts
* fix(ci): await Linux release inventory check
* fix(electron): add frameless window controls on Linux desktop
Linux AppImages were created without native WM decorations and without
in-app controls, leaving users unable to close the window with a mouse.
Treat Linux like Windows: frameless BrowserWindow plus the existing
WindowsWindowControls header buttons and app-menu entry. macOS keeps
hidden title bar with traffic lights unchanged.
Shared usesFramelessElectronChrome() helper drives main window, mini
chat, header insets, and titlebar controls.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Linux desktop feature parity: Open in, background start, tray, multi-window (#2392)
* feat(electron): Linux parity for Open in, background start, and tray
Enable Linux desktop feature parity with macOS/Windows: open projects in
the default file manager and discovered apps, XDG autostart with
--background launches, system tray (including minimize-to-tray), and
tray sync from the renderer.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(electron): allow packaged UI protocol navigations on Linux
Prevent openchamber-ui:// navigations from being handed to
shell.openExternal, which fails on Linux and blocked desktop UI flows.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(ui): surface Linux tray settings in settings search
Include isLinux in settings search runtime context so minimize-to-tray
is discoverable on Linux desktop, matching Windows search behavior.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(electron): stop Linux AppImage Waiting-for-OpenCode flicker
Sync updated boot-outcome init scripts to all BrowserWindows after
desktop_hosts_set, and prefer state.initScript on dom-ready so chooser
reloads inject local/ok instead of a stale not-configured outcome.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(desktop): restore Linux AppImage updater feed and error UX (#2396)
Treat missing latest-linux*.yml (404) as no update available instead of a
hard failure, and stop swallowing updater capability/download errors in the
desktop bridge so About/sidebar can show actionable messages.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* docs: credit Linux AppImage contributors in changelog
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
---------
Co-authored-by: jibanez-staticduo <staticduo@gmail.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>