expand PATH on Linux so desktop-launched clide finds pql (T-347)

A desktop launcher gives the app a minimal PATH (e.g. /usr/bin:/bin) with
no ~/.local/bin, where pql installs — so _findOnPath('pql') returned null,
clide spawned the literal 'pql', and Process.start failed with ENOENT;
the pql pane errored. The PATH re-expansion that re-adds ~/.local/bin +
/usr/local/bin ran on macOS only; Linux GUI launches hit the same wall.

Extend it to Linux (homebrew dirs stay macOS-only). Extract the logic
into a pure expandToolPath() so the platform gating is unit-tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 19:22:12 +02:00
co-authored by Claude Opus 4.8
parent 5bbbc72dab
commit 36f4561ca1
5 changed files with 80 additions and 7 deletions
+22 -7
View File
@@ -145,14 +145,29 @@ String? _firstExisting(List<String> candidates) {
}
/// Build expanded PATH inline — must be self-contained for isolate use.
String _expandedPath() {
final base = Platform.environment['PATH'] ?? '';
if (!Platform.isMacOS) return base;
final home = Platform.environment['HOME'] ?? '';
String _expandedPath() => expandToolPath(
Platform.environment['PATH'] ?? '',
isMac: Platform.isMacOS,
isLinux: Platform.isLinux,
home: Platform.environment['HOME'],
);
/// Pure PATH-expansion logic, extracted so it's testable without touching the
/// process environment.
///
/// A desktop-launched app (macOS or Linux) inherits a minimal PATH that lacks
/// the user bin dirs where tools like `pql` install (`~/.local/bin`), so tool
/// resolution fails even though a terminal launch would find them. Re-add the
/// common user/local bin dirs — that any are missing means they're prepended,
/// so they take precedence over a stale system copy (T-347). Homebrew dirs are
/// macOS-only. On other platforms the base PATH passes through unchanged.
String expandToolPath(String base, {required bool isMac, required bool isLinux, String? home}) {
if (!isMac && !isLinux) return base;
final h = home ?? '';
final extras = <String>[
if (home.isNotEmpty) '$home/.local/bin',
'/opt/homebrew/bin',
'/opt/homebrew/sbin',
if (h.isNotEmpty) '$h/.local/bin',
if (isMac) '/opt/homebrew/bin',
if (isMac) '/opt/homebrew/sbin',
'/usr/local/bin',
];
final existing = base.split(':').toSet();