Skip to content

Run the review server headless and route remote reviews through a gateway - #935

Draft
thesiti92 wants to merge 16 commits into
mainfrom
remote/2-headless-server-gateway
Draft

thesiti92 wants to merge 16 commits into
mainfrom
remote/2-headless-server-gateway

Conversation

@thesiti92

@thesiti92 thesiti92 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Stacked PR 2 of 9 for remote reviews (base: main; #934, the rename, is merged). Review in order; each PR builds and passes its suites on its own.

Manual test plan

Purpose. The CLI can run the review server in the background on any machine (server start --detach, server stop, server reset-id, remote attach), and Desktop's local server gains a gateway that merges, routes and streams other machines' reviews. There is no SSH yet: the dev-only DEV_FAST_REVIEW_REMOTE_HOSTS_FILE hands the gateway its hosts.

Setup. Worktree at origin/remote/2-headless-server-gateway. R up a && R install a. Create the remote review (ID=...).

Steps.

  1. R ssh a -- whiteboard server status --json → ready: true with serverId: the fixture's whiteboard api started a headless server, since no Desktop is on the host.
  2. R ssh a -- whiteboard server stop → Stopped the Whiteboard server (process N).; server status now fails as not ready.
  3. R ssh a -- whiteboard remote attach --json → one JSON line between WHITEBOARD-REMOTE-BEGIN and WHITEBOARD-REMOTE-END: event: "remote.attach", url: http://127.0.0.1:<port>, token, startedServer: true, diffr. Again → startedServer: false, same url.
  4. P=$(R forward a <port>) → prints a free local port.
  5. printf '[{"alias":"devbox","endpoint":{"url":"http://127.0.0.1:%s","token":"%s"}}]' $P <token> > $H/hosts.json.
  6. Launch with DEV_REVIEW_HOME=$H DEV_FAST_REVIEW_REMOTE_HOSTS_FILE=$H/hosts.json pnpm dev; set the Desktop API helpers.
  7. api /remote-hosts → [{"alias":"devbox","serverId":"…","state":"online"}].
  8. api /reviews-api → the array holds Remote-order with "host":"devbox", "hostState":"online".
  9. api /reviews-api/$ID → the remote review, answered through the forward.
  10. Open Remote-order in Desktop, then edit wb-test-a $ID "Edited on the remote." → the text appears in the open tab without a reload.
  11. S wb-test-a 'bash -s -- Pushed' < /tmp/wb-push.sh → a tab "Pushed" opens in Desktop.

Negative checks.

  • curl -s -X DELETE -H "x-review-token: $TOK" $URL/reviews-api/$ID → 404 This route is not available for a review on another machine.
  • Hosts file with a wrong token → state: "offline", detail devbox is offline: it did not accept the token.
  • Add a second entry devbox2 with the same endpoint → devbox2 is duplicate ("… report the same server id …"); Remote-order is listed once.
  • R pause a → offline within about 35 s (30 s heartbeat + 3 s health timeout); the review stays listed with hostState: "offline". R resume a → online.
  • R ssh a -- whiteboard server reset-id while the server runs → refused A Whiteboard server is using … Stop it first, then run whiteboard server reset-id again.
  • R install a --version 0.0.2-e2e; R ssh a -- whiteboard server stop, rerun step 3–5 → incompatible, detail devbox runs Whiteboard 0.0.2-e2e; this Desktop runs 0.2.0. Install Whiteboard 0.2.0 on devbox.
  • Write not json to the hosts file → Desktop's output (the pnpm dev terminal) logs [Whiteboard gateway] Cannot read remote hosts from …: SyntaxError., with no file contents.
  • A remote may send the laptop only authoringCapabilities, openApiReview and focusWindow, and never open another machine's review: not manually drivable; covered by src/server/review-gateway-pushes.test.ts and src/server/global-verb-relay.test.ts.

Cleanup. Common cleanup; rm $H/hosts.json first (it holds a token).

Common setup for all plans

Common setup (read once)

  • Test each PR in a worktree at its head branch: git -C <core> worktree add --detach ../review-prN origin/<head>, then pnpm install there. Run everything below from that worktree root.
  • Helpers (bash or zsh):
R() { node apps/review-desktop/scripts/e2e/remote/remote.mjs "$@"; }
export WB_TEST_RUN=manual-$$                  # before the first `R up`
S() { ssh -F /tmp/wbt.$WB_TEST_RUN/ssh_config "$@"; }   # host aliases are wb-test-<name>
H=/tmp/wb-home-$WB_TEST_RUN                   # isolated Desktop home
mkdir -p $H/review-desktop/state/user-data/User
echo '{"review.experimental.remoteHosts.enabled": true}' > $H/review-desktop/state/user-data/User/settings.json
awk '/createRemoteReview = String.raw`/{f=1;next} /^`;/{f=0} f' apps/review-desktop/scripts/e2e/journeys/remote-host.mjs > /tmp/wb-review.sh
sed -e 's/open\\":false/open\\":true/' -e 's/wbrepo/wbrepo2/g' /tmp/wb-review.sh > /tmp/wb-push.sh
edit() { printf '{"sessionId":"%s","edit":{"type":"insert","content":{"type":"markdown","markdown":"%s"}}}' "$2" "$3" | S "$1" 'whiteboard api session_edit -'; }
  • Launch (dev build only; a packaged build ignores both env vars): DEV_REVIEW_HOME=$H DEV_FAST_REVIEW_SSH_CONFIG=/tmp/wbt.$WB_TEST_RUN/ssh_config pnpm dev (prefix DEV_FAST_REVIEW_DESKTOP_BACKGROUND=1 to keep it from taking focus).
  • Desktop API: D=$(ls $H/review-desktop/instances/dev-*.json); URL=$(node -p "require('$D').url"); TOK=$(node -p "require('$D').token"); api() { curl -s -H "x-review-token: $TOK" "$URL$1"; }
  • A remote review: ID=$(S wb-test-a 'bash -s -- Remote-order' < /tmp/wb-review.sh | head -1) (repo ~/wbrepo, review "Remote-order" with a prose line and a code peek of f.ts). /tmp/wb-push.sh is the same with open: true in ~/wbrepo2.
  • Settings: ⌘, → region Remote hosts → type the alias in SSH alias → Add.
  • Fork unit tests: (cd apps/review-desktop && TSX_TSCONFIG_PATH=tsconfig.test.json node --import tsx --test --test-force-exit <files>). Package tests: pnpm --filter @dev.fast/whiteboard test <files>.
  • Journeys: stage a runtime per apps/review-desktop/scripts/e2e/TESTING.md ("Staging the runtime"), then node apps/review-desktop/scripts/e2e/run.mjs --runtime "$REVIEW_E2E_RUNTIME" --journey <name>.
  • The harness has pause/resume (there is no unpause).
  • Cleanup, every plan: quit Desktop first (its ssh masters count as leftovers), then R down --all; R verify-clean; rm -rf $H /tmp/wb-*.sh. Without an aws sso login session verify-clean also prints AWS could not be checked and exits 1; no other line may appear.

@thesiti92
thesiti92 added this pull request to stack #943 October 5, 2026 19:37
Base automatically changed from remote/1-rename-package to main October 5, 2026 19:58
@thesiti92
thesiti92 force-pushed the remote/2-headless-server-gateway branch 4 times, most recently from 8be70d2 to 49abf5c Compare October 5, 2026 20:41
`server start --detach` runs the headless server in the background, in
its state directory. `server stop` ends only a server the CLI or Desktop
started. `remote attach` starts a server when none is healthy, fetches
diffr into the state directory when the package cannot hold it, and
prints one JSON line between sentinel lines.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 562fd736-d78c-4f16-b9ce-e91003f2f6ed
Agent-Session: c0c53908-0c7b-4e80-a860-a7011b05f0ab
Agent-Session: 6397de47-e94d-43cc-86ac-eba461d48cfe
Agent-Session: 01a0eeba-97ec-71b2-acee-4f5d9a99d47b
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
When no Desktop is running, recorded or installed, the CLI starts the
default headless server instead of failing. Every other case keeps the
old diagnosis.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 562fd736-d78c-4f16-b9ce-e91003f2f6ed
Agent-Session: c0c53908-0c7b-4e80-a860-a7011b05f0ab
Agent-Session: 6397de47-e94d-43cc-86ac-eba461d48cfe
Agent-Session: 01a0eeba-97ec-71b2-acee-4f5d9a99d47b
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
Deleting a review removes its whole checkout directory, including the
checkouts structural diff makes outside the workspace records.

Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 6397de47-e94d-43cc-86ac-eba461d48cfe
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
The headless server prepares and frees a review's pinned checkouts as
Desktop does, and takes over the leases of an owner that died. A remote
caller gets a checkout's state, never its paths or logs.

Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 6397de47-e94d-43cc-86ac-eba461d48cfe
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
Each /watch line names the list or review it carries, so a gateway can
merge the streams of several servers. Repeated subscriptions share one
line, an unchanged list is not sent again, and a missing review is an
error line on an open stream. The client routes each line to its
listeners. The two single-purpose streams had no callers and are gone.

Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 100108d6-116a-4d9b-895d-7626fd8634ee
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
A memory file in the review home maps each remote's stable server id to
its reviews and its last alias, so a review still names its host while
that host is down or renamed.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 100108d6-116a-4d9b-895d-7626fd8634ee
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
Each configured alias is checked through /health, with backoff while it
is down. One server under two aliases is one machine; a copied store is
a duplicate, decided by the order of the setting.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 100108d6-116a-4d9b-895d-7626fd8634ee
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
The Desktop server mounts a gateway that sends each review request in
process to the laptop's routes or over HTTP to the remote that owns the
review, with the remote's token and the caller marked remote. Redirects
and answers that name local paths are refused. GET /remote-hosts reports
each host's state.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 9337555e-60dd-434d-a008-93bdb8ef67e7
Agent-Session: e5763a02-51be-4297-883b-afc6f62e6e37
Agent-Session: 01a0efea-dc89-7e20-a049-3138fe84ceb4
Agent-Session: 100108d6-116a-4d9b-895d-7626fd8634ee
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
The memory file also keeps the last list each server sent, so the owner
of any review in it is known after a restart.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
The gateway lists the laptop's reviews, then each host's in the setting's
order, with the host's state. Each client stream opens one stream to
each machine that owns a review it follows, forwards remote lines as
sent, and marks the reviews of a host that stops answering.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
While a window is attached to the laptop, the gateway attaches to each
online remote's /control stream and relays only capabilities, focus and
opening a review the remote owns. The gateway serves the merged list
and streams.

Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
The laptop's own reviews win over any remote's claim at every
decision. A forwarded answer is cut when it stalls, not by a fixed
limit, and a stream ends when its host goes offline. A remote snapshot
of another review is refused, and its tutorial marker is dropped. With
no host set, the laptop's list and stream pass through as they are.

Agent-Session: 203ee435-a867-494c-bb56-ddde9edf962e
Agent-Session: 879f8dc8-4a2e-4c1d-a221-935df47f9854
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 01a0f84f-dd30-7a41-b2fe-0d7af3946366
Agent-Session: b74726e7-9218-4d00-81bd-c3fc64dcd8d7
Agent-Session: 01a0f894-9661-79c0-a6c4-71002d15105c
Agent-Session: 00102a68-dcd0-4748-a95e-fc417ddbb706
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 10f346e1-a3d6-4004-b9ae-e69332b86ef7
Agent-Session: 61ddd1f7-126b-4756-8f8e-ed5123004afa
Agent-Session: 01a0fde5-5de7-7a00-8f1e-508af5d4455c
Agent-Session: 7d6b1dc9-dc43-474e-a7cf-897a3eb667e1
Agent-Session: 945245a7-5fc9-4d4e-bb9a-8fa4987ac199
Agent-Session: 01a0f7e4-a040-7c70-958e-c32707c30fa1
Agent-Session: 01a0fde5-49f5-7691-b5d7-6bed5e5e4448
Agent-Session: 01a10c6b-6286-7d63-bec6-b36570f309dc
Agent-Session: fe2ac599-fe10-4bdd-a496-a121682ac842
Agent-Session: c7d5d811-b851-4c36-93a4-ea2325ac973a
Agent-Session: 01a10cab-5911-7c00-92f4-5e3404373ba2
Agent-Session: 17be59a9-37ae-45bc-ad47-3cdb1660c6c2
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 01a10cc6-7bb1-7652-8fe2-f99e54e4d14e
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 01a10db4-61fc-7181-82a9-ac2de659fb25
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 01a10d6d-cc61-7a60-8be6-0d3d48878694
Agent-Session: 0742d3f8-2ac6-4fee-8102-c6e930f316ad
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 01a10db4-61fc-7181-82a9-ac2de659fb25
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: 01a10d75-7d32-7f11-8d5a-7aa1c81b5390
Agent-Session: 8a675162-2f63-4f2c-8be7-66b7ae4cdd6a
@thesiti92
thesiti92 force-pushed the remote/2-headless-server-gateway branch from 49abf5c to dad34df Compare October 5, 2026 21:38
The per-host agent now has a timeout, so Node applies the server's Keep-Alive hint and retires idle sockets before the host closes them.

Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: bc41ade8-aab1-4279-b31a-ea472fcfaacc
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: 04f92d25-41e1-4ba0-aef1-7a1a1d409286
Agent-Session: a5134983-fbca-42d2-ac6c-fe14cf3ce20e
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 459ae7ec-7302-42c5-b473-4e315a7e4e19
Agent-Session: 96eed70a-4af6-4249-a91d-8064746610b6
Agent-Session: a5134983-fbca-42d2-ac6c-fe14cf3ce20e
Agent-Session: 01a0fd55-7d25-70c3-bf87-46cdb881d91e
Agent-Session: 9c8a2d13-4198-4d4b-bf1d-4de6fccd0f19
Agent-Session: 99df4638-b570-4eeb-b115-0311294ee04d

This branch has not been deployed

No deployments
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