Skip to content

feat(pty): make the Rust PTY host a checked opt-in with a Node fallback - #1829

Merged
devswha merged 5 commits into
mainfrom
feat/rust-pty-opt-in
Oct 24, 2026
Merged

devswha merged 5 commits into
mainfrom
feat/rust-pty-opt-in

Conversation

@devswha

@devswha devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner

What

The Rust PTY host from #1785 (crates/pty-sidecar) becomes a usable opt-in on Linux and macOS. The Node sidecar stays the default, and the server falls back to it whenever the Rust host cannot do the job. Before this, OVIS_PTY_SIDECAR=rust used the Rust host whenever its file existed. A binary that was present but broken failed the attach. A crash ended the terminal with nothing learned from it.

Turning it on

  • Settings: the same mechanism as every other setting. OVIS_PTY_SIDECAR=rust and OVIS_PTY_SIDECAR_BIN=<binary> go in the environment, or for the plugin install in herdr's plugin env file. There is no in-app switch, so i18n and the Settings UI are untouched.
  • ~/ paths: a leading ~/ in OVIS_PTY_SIDECAR_BIN is expanded, because the plugin env file is not a shell.
  • Installed apps: the crate README explains that an installed app needs its own path for the binary. An update installed from the app runs from ~/.config/ovis/updates/, where the default relative build path does not exist.
  • Bad values: a value of OVIS_PTY_SIDECAR other than rust or node is reported once and means Node.

When the Rust host cannot run (server/pty/host.ts, server/pty/session.ts)

  • A check before first use, once per binary path per process. It runs at startup, next to the existing Node probe, when Node can run the sidecar. Any other value of OVIS_PTY_SIDECAR than node is looked at then too.
    • The binary run with no arguments must print pty-sidecar: usage: and exit 2. This checks it exists, executes, matches this CPU/OS and is this program.
    • <bin> 1 1 true must exit 0, so a pty can be opened, forked into and reaped here.
    • Each run has 3 s and is killed with SIGKILL past it, so a binary that ignores SIGTERM cannot hold the server's start. A timeout counts as a failure even though the host exits 0 on a SIGTERM.
    • A failure is logged once with its reason (ENOENT, EACCES, ENOEXEC, not the Rust PTY host (exit 0), a signal name, or a timeout), and every attach uses Node.
  • A binary that cannot be started after passing (removed or replaced since): that attach starts on Node. The Rust host is then disabled only once Node did start. If both spawns fail, the error propagates to terminal-process.ts as today and nothing is disabled.
  • A breaker: a Rust host that ends by a signal the server did not send (a crash re-raising SIGSEGV or SIGABRT, the OOM killer) makes every later attach use Node until the server restarts. That attach itself ends as an attach does when its host stops.
    • The server's own kills never count, including a kill right after spawning: closed is set before proc.kill().
    • The trip happens before onExit, because onExit can start the next session synchronously.
  • PtySession.host says which host a session runs on. The parity tests and the bench assert it, so a disabled Rust host can never silently turn the Rust checks into Node runs.

Not changed

  • Whether a pane attaches or is mirrored still depends on Node + node-pty (sidecarAvailable()). That answer is cached for the server's life in server/core/server-core.ts, and this PR leaves that file alone. A breaker that could falsify a Rust-only answer would leave a Node-less PC with failing attaches until restart.
    • With the Rust host asked for on a PC without Node, the server says once that panes are mirrored.
  • The installers still ship Node.
  • Windows and the remote PC bundles always use the Node sidecar (or mirror).

CI

A new Rust PTY host job runs on GitHub's Ubuntu image, which has a Rust toolchain; the self-hosted runners do not have one. It builds the crate with --locked, runs cargo test (the frame parser's tests never ran in CI before), runs server/pty/host.test.ts (so the Rust parity cases run instead of skipping), and runs server/pty/session.test.ts with OVIS_PTY_SIDECAR=rust. The build takes about 6 s cold. The job is not a required check.

Tests

server/pty/host.test.ts: 17 new tests, using fake hosts written to a mkdtemp directory so they run without cargo. ptyHost, which nothing called any more, is gone, and its tests now call rustSidecar.

  • The probe:
    • It passes the built host.
    • It refuses /bin/true and another program's usage line.
    • It names EACCES, ENOEXEC and ENOENT. Refusals are checked by their cause (exit code, signal, errno, timeout), not their wording.
    • A host that hangs fails, including one that answers the timeout's SIGTERM with exit 0 and one that ignores SIGTERM.
    • A crash and a nonzero exit on the pty leg fail.
    • Both bridge tokens are scrubbed from both probe runs.
  • The policy:
    • A path is probed once and warned about once.
    • A passing path is announced once.
    • ~ and ~/ expand, while ~user and absolute paths stay as they are.
    • Unknown values warn once, and node, empty and unset are silent.
  • PtySession:
    • It starts on Node when the binary vanished after the probe.
    • The breaker trips before onExit on a signal death the server did not send.
    • It keeps the Rust host after its own immediate kill, 20 times over.
    • Nothing is disabled when both hosts fail to start.
  • Existing tests: the parity blocks reset host state and assert the host of every session, and the missing-binary test now expects exactly one warning.

Mutation check: each mechanism was broken on purpose at the final commit, by a script in a scratch worktree, and its test failed (14 mutations):

  • the identity check;
  • the pty leg;
  • the timeout check;
  • the signal check;
  • token scrubbing;
  • the verdict cache;
  • the unknown-value warning;
  • ~ expansion;
  • the constructor fallback;
  • the breaker, removed or moved after onExit;
  • the our-kill guard;
  • disabling before Node started;
  • SIGKILL on a timed-out run (the new test then hangs).

With everything restored, 41 tests pass and 3 skip.

Verification

  • PTY tests: bun test ./server/pty/host.test.ts gave 41 pass, 3 skip (the Rust-only cases in the Node block), 0 fail. bun test ./server/pty/session.test.ts passed 9/9 on Node and 9/9 with OVIS_PTY_SIDECAR=rust.
  • Other suites: bun test ./server/machines.test.ts, the conventions tests and bun run typecheck pass. cargo test passes for the crate.
  • Real browser, with the isolated test herdr session (a server from createServer on loopback, headless Chromium on ?pane=):
    • Rust host: attach, typed input echoed back, Ctrl+C ending sleep 30, and two resizes (smaller, then larger) each checked with stty size inside the pane. The attach's parent process was ovis-pty-sidecar.
    • Node, same scenario: passes too. Three runs on each host: herdr sometimes applies a resize to the pane a moment after the attach does, on both hosts, so the check asks stty again until the size arrives (at most 15 tries; Node needed a second ask in 2 of 3 runs).
    • The host SIGKILLed mid-attach: pty-exit code 137, one breaker line, and after a reload the attach runs on node pty-host.mjs and takes input.
    • Broken binaries:
      • OVIS_PTY_SIDECAR_BIN=/bin/true, a missing path and a non-executable file each produce one startup warning (not the Rust PTY host (exit 0), ENOENT, EACCES), and the attach runs on Node.
      • OVIS_PTY_SIDECAR_BIN=~/.cache/…/ovis-pty-sidecar runs on Rust.
    • No node on PATH, with OVIS_PTY_SIDECAR=rust: /api/health reports terminal_attach: false, terminal_mirror: true, plus the one warning.
  • Contract tests against the isolated test herdr: attach-held, take-over, keys-lifecycle, output and reattach gave 46/46 on Node. With OVIS_PTY_SIDECAR=rust they gave 44/46. The two are the output cases that remove node from PATH to make the attach's spawn fail; the Rust host starts by its path and does not fail there, as noted in feat(pty): add an experimental Rust PTY host behind OVIS_PTY_SIDECAR #1785. CI runs them on Node.
  • bun run check fast: all steps ok on the final commit (workflow syntax with actionlint, generated files, typecheck, build, unit tests 6380 pass / 0 fail), exit 0. The browser runs were repeated after the last commit: Rust attach, /bin/true falling back with its startup warning, and OVIS_PTY_SIDECAR=RUST reported at startup.
  • Code review (a code-review agent, before the final commit): approve, no blockers. It reproduced one real defect, a binary that ignores SIGTERM holding the startup check (fixed by SIGKILL, with a test), and the nits were addressed.
  • Gate review (a gate-review agent): approve at the final commit, after a first pass asked for the mutation logs and the code-review report as files. It re-ran the PTY suites (50 pass, 3 skip), cargo test (15/15) and the no-Node check, and read every mutation log.

Review

This changes how the server spawns terminal attaches when the opt-in is set, and adds a CI job, so it waits for a real review. It touches no file another open PR touches.

The Rust PTY host's PtySession checks skip without a build, and the self-hosted runners have no
Rust toolchain. The Rust PTY host job runs on GitHub's Ubuntu image, which has one: it builds the
host, runs cargo test, then host.test.ts and session.test.ts with the Rust host in place.
OVIS_PTY_SIDECAR=rust used the Rust host whenever its file existed. Now the server checks the
binary once per path before using it (at startup when Node can run the sidecar): run with no
arguments it must print its usage line and exit 2, and `1 1 true` must exit 0 within 3 s. A
binary that is missing, not executable, not for this CPU, another program, or that crashes,
hangs or cannot open a pty is reported once with the reason, and every attach uses Node.

PtySession starts an attach on Node when the Rust binary cannot be started after passing (and
only once Node did start), and a Rust host that ends by a signal the server did not send makes
every later attach use Node until the server restarts. A session the server kills, even right
after spawning it, never counts. PtySession reports the host it runs on (`host`), which the
parity tests and the bench assert.

A leading ~/ in OVIS_PTY_SIDECAR_BIN is expanded, as herdr's plugin env file is not a shell, and
a value of OVIS_PTY_SIDECAR other than rust or node is reported once. Whether a pane attaches
still depends on Node: with the Rust host asked for on a PC without Node, the server says that
panes are mirrored. Node stays the default.
… it cannot run

The plugin env file lines, why an installed app needs an absolute or ~/ binary path (in-app
updates run from ~/.config/ovis/updates), the checks before first use, the fallbacks, and that
attach versus mirror still depends on Node.
The check's runs had a 3 s timeout, but Bun ends a timed-out run with SIGTERM, which a binary
that ignores it outlives: the check, which runs at startup, then held the server's start for good.
Each run past its time is now killed with SIGKILL; a test runs a fake host that ignores SIGTERM.

Also from review: a value of OVIS_PTY_SIDECAR other than node is now reported at startup, not
on the first attach; the no-Node warning is not given on Windows, where the Rust host never runs;
ptyHost, which nothing used any more, is gone; one helper says why a spawn threw; and the tests
check the cause in a refusal (exit code, signal, errno, timeout) instead of its wording.
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 34 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1a83fc4 and b84227b.

Files selected for processing: 8
  • .github/workflows/ci.yml
  • changelog.d/rust-pty-host-opt-in.md
  • crates/pty-sidecar/README.md
  • scripts/pty-sidecar-bench.ts
  • server/pty/host.test.ts
  • server/pty/host.ts
  • server/pty/session.ts
  • server/pty/sidecar.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devswha

devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Merge pass review-work for b112b23: REVIEW FAILED on one stated behaviour. Everything else holds up well.

Blocker: an invalid OVIS_PTY_SIDECAR value isn't reported when the PC has no Node. The description says "A value of OVIS_PTY_SIDECAR other than rust or node is reported once and means Node." In server/pty/sidecar.ts:63-64, when known is false (no Node for the sidecar), only the exact value rust gets a message. Any other value, RUST or a typo for example, is silent: rustSidecar() is never reached, and no other code reports it. The gate reproduced this. Repeated sidecarAvailable() calls return {available:false, again:false, errors:[]} with no warning. Please check whether the value is valid regardless of Node availability, for example by reporting an unknown value before the known branch, and add a test at that entry point. It's a small change, and since it's behaviour in server/, it's worth a CodeRabbit re-review once pushed.

Checked and passing:

  • 55 PTY tests and the typecheck pass. Locally, cargo build --release --locked builds the host and cargo test passes 15/15. With the binary present, host.test gives 41 pass and 3 skip, and session.test with OVIS_PTY_SIDECAR=rust passes 9/9.
  • Code review (programming + remove-ai-slops) PASS. These mutants fail the tests: no breaker, no timeout, disabling Rust before Node starts, and the breaker moved after onExit. Without SIGKILL the run hangs, so that mutant is caught as a hang. The check costs at most 2×3 s once at startup, and about 3 ms on the real binary. No breaker race was found.
  • Gate: the probe validation, the bounded SIGKILL, the post-probe Node fallback, failure of both hosts, the breaker ordering and the PtySession.host assertions all pass. The PR's Rust PTY host CI log shows all 10 Rust parity cases, the 15 cargo tests and the stress and crash cases actually ran.
  • Workflow (rust-pty-host job): a read-only checkout (persist-credentials: false), no secrets, a sensible needs/if, a draft skip, and the existing jobs are unchanged.

Notes, non-blocking:

  • MINOR: the CI job could pass without Rust coverage if the binary's check failed on the runner. It didn't in this run. Asserting session.host === "rust" in the Rust-configured step would close that gap.
  • host.test.ts is now about 600 lines.

CodeRabbit was rate-limited, so this review stands in for it. Its findings and their resolution go on this PR before the merge.

@devswha

devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Fixed the blocker in b84227b: an invalid OVIS_PTY_SIDECAR is now reported on a PC without Node too.

  • server/pty/sidecar.ts: the startup word moved into announcePtyHost(sidecar, env), which sidecarAvailable() calls once. Any value other than node or rust (for example RUST or a typo) goes to rustSidecar(), whatever Node's state. That path reports it once (OVIS_PTY_SIDECAR=RUST: expected "node" or "rust"; using the Node PTY sidecar) and returns before any probe. rust without Node still gets its own message, and the Rust host is never probed there.
  • server/pty/host.test.ts: new test "reports an unknown value at startup even on a PC without Node, and never probes there". With Node unavailable, RUST is reported once, rust gets the no-Node message, and node, empty and unset stay silent. Bun.spawnSync is never called. The test fails with the old condition (if (sidecar) rustSidecar(env)): 0 pass, 1 fail. It passes with the fix.
  • bun test server/pty/host.test.ts server/pty/session.test.ts server/machines.test.ts: 113 pass, 3 skip, 0 fail. bun run check fast passed before the push.

I left the MINOR notes for later: asserting session.host === "rust" in the CI step, and host.test.ts's size.

@devswha

devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Codex review of b84227b (gpt-6.1-sol, service tier fast, reasoning xhigh, read-only brief): No findings. It checked announcePtyHost and its once-per-process call from sidecarAvailable, confirmed that the no-Node path has no reachable probe or spawn, and checked the Windows behaviour, the Node-available path, and that the new host.test.ts case fails without the fix and does not depend on timing.

@devswha

devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner Author

Merge pass review-work report. Overall: PASSED. This PR adds a CI workflow job and CodeRabbit was rate-limited, so per AGENTS.md the independent review and how each finding was resolved are recorded here and in the earlier comment.

Lane Verdict Confidence
Manual QA (rows 1-6, 7r; artifacts kept) PASS at b84227b -
Code review (omo-native-code-reviewer, programming + remove-ai-slops) PASS (WATCH) -
Gate round 1 (b112b23) REJECT: an invalid OVIS_PTY_SIDECAR value went unreported on a PC without Node HIGH
Gate round 2 (b84227b, fresh reviewer) APPROVE HIGH

Manual QA

  • Locally, cargo build --release --locked builds the Rust host, and cargo test passes 15/15.
  • With the binary present, host.test.ts passes 42 with 3 intentional skips, and session.test.ts passes 9/9 with OVIS_PTY_SIDECAR=rust.
  • The typecheck passes, and git merge-tree is clean against main.

Code review

  • These mutants fail a test: no breaker, no timeout, Rust disabled before Node starts, and the breaker moved after onExit. A mutant without SIGKILL hangs.
  • The startup check costs at most 2 × 3 s, once, and about 3 ms with the real binary.
  • No breaker race was found.

The rust-pty-host job

  • Read-only checkout (persist-credentials: false), no secrets, sensible needs/if, and it's not a required check.
  • Its CI log shows all 10 Rust parity cases, the 15 cargo tests and the stress and crash cases actually ran.

Round 1's finding, fixed in b84227b: announcePtyHost reports an unknown value exactly once, with or without Node. The no-Node message for rust is unchanged, and nothing probes on a PC without Node. The gate confirmed this in ten fresh-process checks.

Follow-ups (MINOR)

  • The CI job could pass without Rust coverage if the binary's check failed on the runner. It didn't here; asserting session.host === "rust" would close that gap.
  • host.test.ts has grown to about 600 lines.

All required checks are green, and no review thread is open.

CodeRabbit did not review this PR (rate-limited or skipped). The reviews above stand in for it.

@devswha
devswha merged commit 3597f45 into main Oct 24, 2026
18 checks passed
@devswha
devswha deleted the feat/rust-pty-opt-in branch October 24, 2026 14:07
devswha pushed a commit that referenced this pull request Oct 24, 2026
#1829 added a rust-pty-host job to ci.yml with actions/checkout@v7. It now
uses the same v7.0.1 commit SHA as every other checkout; it already kept no
Git credential. Without the pin, the action audit in scripts/ci-setup.test.ts
names that step and fails.
devswha added a commit that referenced this pull request Oct 24, 2026
…ecked (#1859)

Step 1 of making the Rust PTY host the default on Linux and macOS (Node
becomes optional): ship the binaries with every release and install
them, checked.

## What changes
- **New workflow `pty-sidecar.yml` (Rust PTY host binaries)**: builds
`ovis-pty-sidecar` for linux-x64 and linux-arm64 (static musl, so no
glibc floor) and a universal (arm64 + x86_64), ad-hoc signed macOS
binary. It runs `cargo test` on each and, on Linux, `host.test.ts` +
`session.test.ts` on the built binary. It writes `ovis-pty-sidecar.json`
(version, the `crates/pty-sidecar` git tree, SHA-256 per platform) and
`SHA256SUMS`. It runs on PRs touching the host/PTY code, is called by
Release, and can be dispatched with a tag to attach the binaries to an
existing release.
- **Release** builds them in parallel with validation and attaches them
in `gh release create`, so no tag exists without them.
- **`scripts/pty-sidecar.ts install`**: fetches the manifest for
`v<package.json version>`. It installs into `bin/ovis-pty-sidecar` only
when the crate tree matches this checkout, the SHA-256 matches, and the
binary answers as the host. The move is one rename, so a failure leaves
nothing behind. Otherwise it says why and exits 0: that install keeps
the Node sidecar.
- It runs as a herdr plugin `[[build]]` step (Linux/macOS), after each
update the app installs (`server/updater.ts`, failures logged and
ignored), and from `install.sh` for installs that predate it.
- **Remote PC bundles** carry the host in `bin/`; the smoke checks that
it runs. `scripts/pty-sidecar.ts` and `crates/pty-sidecar` are bundle
inputs for the release guards.
- **`server/pty/host.ts`** looks at `bin/ovis-pty-sidecar` before
`target/release`.

This does **not** change the default: the Rust host still needs
`OVIS_PTY_SIDECAR=rust`. The default flip comes after #1829, which this
PR does not touch (the only overlap is `host.ts`'s default path, a
one-line rebase either way).

## Verification
- `bun run check fast`: all green (unit 6392 pass, 0 fail).
- A static musl build passes `session.test.ts` + `host.test.ts` with
`OVIS_PTY_SIDECAR=rust` (32 pass, 0 fail).
- `install` against a local fake release: it installs the binary and
keeps it on a rerun. A tampered binary is refused with a SHA-256
mismatch and leaves no `bin/`. A manifest from other crate sources is
refused. An unreachable release leaves Node in use, with exit 0 (exit 1
with `--strict`). `scripts/pty-sidecar.test.ts` covers these cases.
- This PR's own **Rust PTY host binaries** run exercises the three
builds and the manifest.

**Needs a real review**: this changes workflows (Release, Remote PC
bundles, a new one) and the installer path.

---------

Co-authored-by: mp <mp@local>
devswha pushed a commit that referenced this pull request Oct 24, 2026
#1829 added a rust-pty-host job to ci.yml with actions/checkout@v7. It now
uses the same v7.0.1 commit SHA as every other checkout; it already kept no
Git credential. Without the pin, the action audit in scripts/ci-setup.test.ts
names that step and fails.
devswha added a commit that referenced this pull request Oct 24, 2026
…s the fallback (#1908)

Step 2 of removing Node from Linux and macOS installs. It builds on
#1829 (the Rust PTY host as a checked opt-in) and #1859 (release
binaries installed into `bin/ovis-pty-sidecar`, checked against the
release's SHA-256).

## What changes
- **Rust by default.** On Linux and macOS, `server/pty/host.ts` uses the
Rust PTY host whenever it passes its startup check. That host is the
installed release's (its record vouches for it), else a local build,
else `OVIS_PTY_SIDECAR_BIN`. `OVIS_PTY_SIDECAR=node` asks for the Node
sidecar. Unknown values are reported once and mean Node. A checkout
without a host says so once, as a log line.
- **A PC without Node attaches.** `sidecarAvailable()` is true when the
Rust host passes or Node with node-pty can run. With neither, panes are
mirrored, and the server logs which way they go. The production check
and the test check share one rule.
- **The Node fallback never loads node-pty inside Bun** (AGENTS.md):
- `PtySession` probes the `node` it will spawn on the spawn's own PATH,
requires Node 18 or newer, and spawns that absolute path.
- `pty-host.mjs` exits 70 before importing node-pty when it runs under
Bun.
- **Breaker.** A Rust host ended by a signal turns the Rust host off
only where Node can take over. On a PC without Node it is kept and
logged, so one crash does not leave every later attach without a host.
- **Installer.**
- `scripts/preflight.sh` no longer requires Node; it only notes an old
one.
- `install.sh` installs Node 22 only when the Rust host does not run
here, using the server's own two-step check of the binary.
  - A failed Node install is a warning, not an unfinished install.
- For an older release whose build step still asks for Node,
`install.sh` installs Node and retries once.
- **Docs.** INSTALL.md (including what a source checkout needs), README
in English, Korean, Japanese and Chinese, `docs/guide.md`, AGENTS.md,
CONTRIBUTING.md, the crate README and a changelog fragment now say Node
is optional.

## Verification
- `bun run check fast` on this head: see the comment below.
- PTY, sidecar and installer tests on this head: 166 pass, 0 fail. The
new tests simulate a PC without Node by putting a Bun-as-`node` on PATH,
and each fails when its fix is reverted:
  - the breaker keeps the Rust host;
  - Bun is never run as the Node host;
  - the server attaches on Rust alone and mirrors with neither.
- **Real checks on this code** (step 3, before any release). These used
#1859's CI binaries in `bin/` with no Node on PATH, in a fresh Ubuntu
24.04 container and on eamac (macOS, fresh `/tmp` HOME, isolated herdr
session). Each machine passes three cases:
- **Rust host:** attach, typing, resize, about 4 MB of output, and close
with no host left. First paint was 285 ms on Linux and 139 ms on eamac.
- **Broken binary, no Node:** the pane is mirrored, and the log says so.
  - **Broken binary, with Node:** the Node sidecar attaches.
- **Reviews.** omo-native-code-reviewer found one blocker (the breaker
on a PC without Node) and four should-fix items. Codex (gpt-6.1-sol,
fast, xhigh) found four more: the node probed versus the node spawned,
Node 18 or newer, an older release's preflight, and `install.sh`'s check
of the binary. All are fixed in this commit. The code is the one
reviewed, rebased onto main with no conflicts.

## Not covered here
Only a published release can prove the `install.sh` and `herdr plugin
install` paths with no Node. Those fetch the host by tag, so they need a
release cut with #1859 and this PR. Removing the Node sidecar itself is
a later step.

**Needs a real review:** this changes the installer, the plugin build's
preflight and the PTY host default.

---------

Co-authored-by: mp <mp@local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant