fix(ipc): the client is found on ARM too, and a relative path is refused instead of run #1

Merged
enricobuehler merged 2 commits from worktree-exec-binary-resolution into main 2026-08-03 16:49:22 +00:00
Owner

Two bugs in how the Linux/macOS backend decides which VirtualHere binary to run, both surfaced by a user (RoobN) whose plugin could not use a client that was installed and working.

The PATH probe only ever tried one name

KNOWN_BINARIES has listed four architecture variants since the first commit, but resolveBinary only ever returned KNOWN_BINARIES[0]. On anything that is not x86_64 the plugin therefore asked for vhclientx86_64, got ENOENT, and told the operator to install the client they already had.

It now probes PATH across every name and hands back the absolute path it found.

The absolute-path rule was documented but never implemented

Both this file and the README have said since the start that an operator-supplied clientBinary "must be an absolute path; anything else is rejected rather than executed". Nothing enforced it — whatever the operator typed went straight to execFile.

So a bare name silently resolved out of the runner's PATH, which is not the PATH of the shell they tested in and which they cannot see. It is now enforced, and the message says which of the two mistakes was made rather than just failing.

Failure surfaces where it can be read

Resolution failure is carried to the first send as an ordinary VhIpcError rather than failing the layer, so the plugin stays up and the Diagnostics tab (and doctor) render the reason with its remedy. Losing the console page that explains a missing client would be a poor trade for a client that is missing by default.

The /tmp note

Also records, here and in the README, that the /tmp FIFOs this backend depends on were invisible to the plugin runner on punktfunk 0.23.0 and earlier: the punktfunk-scripting unit set PrivateTmp=yes, so the binary launched and could never reach the daemon behind it. That is the shape of the original report — works in a shell, fails from the plugin, and no config change helps. Fixed host-side in unom/punktfunk#27; the README carries the systemctl --user edit drop-in for anyone on an older host.

Verification

  • bun test — 73 pass, 0 fail (10 new, covering the probe, the absolute-path refusal, and the unresolved-binary error path)
  • bun run typecheck — clean across all three workspaces
  • bunx biome check . — clean

🤖 Generated with Claude Code

Two bugs in how the Linux/macOS backend decides which VirtualHere binary to run, both surfaced by a user (RoobN) whose plugin could not use a client that was installed and working. ## The PATH probe only ever tried one name `KNOWN_BINARIES` has listed four architecture variants since the first commit, but `resolveBinary` only ever returned `KNOWN_BINARIES[0]`. On anything that is not x86_64 the plugin therefore asked for `vhclientx86_64`, got `ENOENT`, and told the operator to **install the client they already had**. It now probes `PATH` across every name and hands back the absolute path it found. ## The absolute-path rule was documented but never implemented Both this file and the README have said since the start that an operator-supplied `clientBinary` "must be an absolute path; anything else is rejected rather than executed". Nothing enforced it — whatever the operator typed went straight to `execFile`. So a bare name silently resolved out of the **runner's** `PATH`, which is not the `PATH` of the shell they tested in and which they cannot see. It is now enforced, and the message says which of the two mistakes was made rather than just failing. ## Failure surfaces where it can be read Resolution failure is carried to the first `send` as an ordinary `VhIpcError` rather than failing the layer, so the plugin stays up and the **Diagnostics** tab (and `doctor`) render the reason with its remedy. Losing the console page that explains a missing client would be a poor trade for a client that is missing by default. ## The `/tmp` note Also records, here and in the README, that the `/tmp` FIFOs this backend depends on were invisible to the plugin runner on punktfunk 0.23.0 and earlier: the `punktfunk-scripting` unit set `PrivateTmp=yes`, so the binary launched and could never reach the daemon behind it. That is the shape of the original report — works in a shell, fails from the plugin, and no config change helps. Fixed host-side in `unom/punktfunk#27`; the README carries the `systemctl --user edit` drop-in for anyone on an older host. ## Verification - `bun test` — 73 pass, 0 fail (10 new, covering the probe, the absolute-path refusal, and the unresolved-binary error path) - `bun run typecheck` — clean across all three workspaces - `bunx biome check .` — clean 🤖 Generated with [Claude Code](https://claude.com/claude-code)
enricobuehler added 2 commits 2026-08-03 16:33:14 +00:00
Two bugs in how the Linux/macOS backend decides which VirtualHere binary to
run, both reported by a user whose plugin could not use a client that was
installed and working.

`KNOWN_BINARIES` has listed four architecture variants since the first commit,
but `resolveBinary` only ever returned the first of them. On anything that is
not x86_64 the plugin therefore asked for `vhclientx86_64`, got ENOENT, and told
the operator to install the client they already had. It now probes PATH across
every name and hands back the absolute path it found.

The absolute-path rule was documented in this file and in the README from the
start — "anything else is rejected rather than executed" — and was never
implemented: whatever the operator typed went straight to execFile. So a bare
name silently resolved out of the *runner's* PATH, which is not the PATH of the
shell they tested in and which they cannot see. It is now enforced, and says
which of the two mistakes was made.

Resolution failure is carried to the first send as an ordinary VhIpcError rather
than failing the layer, so the plugin stays up and the Diagnostics tab (and
`doctor`) can render the reason with its remedy — losing the console page that
explains a missing client would be a poor trade for a client that is missing by
default.

Also records, here and in the README, that the `/tmp` FIFOs this backend depends
on were invisible to the plugin runner until punktfunk 0.23.1: the unit set
PrivateTmp=yes, so the binary launched and could never reach the daemon behind
it. That is the shape of the original report — works in a shell, fails from the
plugin, and no config change helps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs: don't name a release that doesn't exist yet
CI / build (pull_request) Successful in 2m4s
CI / publish (pull_request) Skipped
7d3654ad41
The /tmp and log-page notes referenced punktfunk 0.23.1 as the version carrying
the fix. 0.23.0 is the latest tag and the next number isn't decided, so that
claim could simply be wrong on arrival. Phrase both against 0.23.0, which is a
fact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
enricobuehler merged commit 768cf2f460 into main 2026-08-03 16:49:22 +00:00
enricobuehler deleted branch worktree-exec-binary-resolution 2026-08-03 16:49:25 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk-plugin-virtualhere#1