Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See LICENSE in the repository root for license information.
*--------------------------------------------------------------------------------------------*/

import type { ReviewRemoteTarget } from "./reviewRemoteProbe.js";
import { REVIEW_REMOTE_INSTALL_LOCK, REVIEW_REMOTE_LOCK_STALE_SECONDS, REVIEW_REMOTE_VERSION, REVIEW_REMOTE_WRAPPER_MARK } from "../../common/reviewProtocol.js";

export { REVIEW_REMOTE_LOCK_STALE_SECONDS, REVIEW_REMOTE_VERSION, REVIEW_REMOTE_WRAPPER_MARK };
Expand Down Expand Up @@ -209,11 +210,12 @@ say NODE-OK

export function packageInstallScript(
context: ReviewRemoteInstallContext,
input: { version: string; sha512: string; node: string; npm: string; registry?: string },
input: { version: string; target: ReviewRemoteTarget; sha512: string; node: string; npm: string; registry?: string },
): string {
if (!/^[0-9a-f]{128}$/.test(input.sha512)) throw new Error("The package checksum is not a sha512.");
const nodeBin = input.node.slice(0, input.node.lastIndexOf("/"));
const registry = input.registry ? ` --registry=${shellQuote(input.registry)}` : "";
// --omit=optional skips unused agent binaries, so diffr's platform package is named directly.
return `${prelude(context)}own
p=${shellQuote(versionPart(context, input.version))}
f="$p/package.tgz"
Expand All @@ -224,7 +226,8 @@ sum=\${sum%% *}
[ "$sum" = ${input.sha512} ] || { rm -rf "$p"; say MISMATCH "$sum"; exit 3; }
PATH=${shellQuote(nodeBin)}:$PATH
export PATH
guard ${shellQuote(input.npm)} install --ignore-scripts --omit=optional --no-audit --no-fund --no-update-notifier --loglevel=error --cache "$p/.npm-cache" --prefix "$p"${registry} "$f" > "$p/.npm.log" 2>&1 || {
dv=$(tar -xzOf "$f" package/package.json 2>/dev/null | sed -n 's/.*"@dev\\.fast\\/diffr": *"\\([0-9][^"]*\\)".*/\\1/p' | head -n 1)
guard ${shellQuote(input.npm)} install --ignore-scripts --omit=optional --no-audit --no-fund --no-update-notifier --loglevel=error --cache "$p/.npm-cache" --prefix "$p"${registry} "$f" \${dv:+"@dev.fast/diffr-${input.target}@$dv"} > "$p/.npm.log" 2>&1 || {
tail -n 15 "$p/.npm.log" >&3
rm -rf "$p"
fail npm could not install the package
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ test("an install has the adapters but not the bundled agent binaries; images dec
assert.equal(await inContainer("node", `test -f ${modules}/@agentclientprotocol/codex-acp/dist/index.js && echo yes`), "yes");
assert.equal(await inContainer("node", `test -f ${modules}/@agentclientprotocol/claude-agent-acp/dist/index.js && echo yes`), "yes");
assert.equal(await inContainer("node", `ls -d ${modules}/@openai/codex-* ${modules}/@anthropic-ai/claude-agent-sdk-* 2>/dev/null | wc -l`), "0");
assert.equal(await inContainer("node", `test -x ${modules}/@dev.fast/diffr-linux-*/diffr && echo yes`), "yes");
assert.equal(await version("node"), VERSION);

await inContainer(
Expand Down Expand Up @@ -195,6 +196,7 @@ test("a sealed host gets Node by upload and the dependencies through the relay",
{ step: "package", via: "upload" },
]);
assert.equal(await version("sealed"), VERSION);
assert.match(await inContainer("sealed", `~/.dev/whiteboard-remote/versions/${VERSION}/node_modules/@dev.fast/diffr-linux-*/diffr --version`), /^diffr /);
assert.equal(await inContainer("sealed", "ss -Htln | grep -c 127.0.0.1: || true"), "0");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ export async function installRemote(input: ReviewRemoteInstallInput): Promise<Re
"installing the package",
packageInstallScript(context, {
version: input.version,
target: input.target,
sha512,
node,
npm,
Expand Down
9 changes: 8 additions & 1 deletion apps/review-desktop/scripts/e2e/journeys/remote-install.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,15 @@ async function steps(ctx, until, watch, timings, manifestPath) {
onRemote(sealed, "curl -sS -m 5 -o /dev/null https://registry.npmjs.org/"),
"the sealed host reaches the registry",
);
assert.match(
await onRemote(
sealed,
"ls ~/.dev/whiteboard-remote/versions/*/node_modules/@dev.fast/diffr-linux-*/diffr",
),
/diffr$/,
);
ctx.check(
`3. ${sealed}: Node and the package uploaded from this computer, npm through the relay; online ${third.ms} ms after Install; the host still has no route out`,
`3. ${sealed}: Node and the package uploaded from this computer, npm through the relay; online ${third.ms} ms after Install; the host still has no route out, and diffr came through the relay`,
);

// 4. old: glibc 2.31 is refused before anything is written, and no question is asked.
Expand Down
2 changes: 1 addition & 1 deletion docs/remote-hosts.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ host at once take turns.

| Path | What it is |
|---|---|
| `~/.dev/whiteboard-remote/versions/<version>/` | One Whiteboard version: the package, its dependencies, a `whiteboard` launcher and a marker file that records what was checked. |
| `~/.dev/whiteboard-remote/versions/<version>/` | One Whiteboard version: the package, its dependencies and the host's `diffr` for structural diff, a `whiteboard` launcher and a marker file that records what was checked. |
| `~/.dev/whiteboard-remote/node/v<node version>/` | Node 24, only when the host has none. |
| `~/.dev/whiteboard-remote/install.lock/` | Present while an install runs. |
| `~/.local/bin/whiteboard` | A launcher for the newest version, so that you and your agents can run `whiteboard` there. Desktop writes it only if that path is free or Desktop's own; a `whiteboard` you installed yourself is left alone. |
Expand Down
Loading