Files
paseo/packages/cli/src/run.ts
T
Mohamed BoudraandGitHub d2de309fc3 Make relay opt-in when pairing devices (#2706)
* feat: make relay opt-in for device pairing

* fix(relay): keep pairing state authoritative

* fix(relay): refresh pairing state across transports

* fix(onboard): honor explicit relay opt-out

* fix(relay): surface transport startup failures

* fix(pairing): gate offers for older daemons

* test(cli): rely on real pairing transport coverage

* fix(cli): report live relay without a pid file

* fix(relay): synchronize config during daemon startup

* fix(relay): preserve mutability for ignored overrides

* fix(cli): use reachable daemon for pairing

* fix(app): redirect invalid pair device routes

* fix(pairing): support remote host device pairing

Keep Pair Device host-relative through the existing settings and daemon RPC flow. Route CLI output through an injected adapter so workflow tests do not mutate process globals.

* fix(pairing): validate pairing destinations

Expose the host-relative Pair Device flow on every supported app platform. Reject a reachable daemon whose identity does not match the requested Paseo home before reading or mutating its pairing state.

* fix(pairing): render QR codes across platforms

Generate SVG text without DOM or canvas and render it through the existing cross-platform SVG stack.

* fix(cli): pair from persisted relay state

Allow explicit relay pairing while the daemon is stopped when relay is already enabled in persisted configuration.
2026-08-01 04:35:06 +08:00

54 lines
1.6 KiB
TypeScript

import { createCli } from "./cli.js";
import { classifyInvocation } from "./classify.js";
import { openDesktopWithProject } from "./commands/open.js";
export interface RunCliOptions {
cwd?: string;
nodeArgv?: [string, string];
}
export function createCliParseArgv(input: {
argv: string[];
cwd: string;
nodeArgv?: [string, string];
}): string[] | { kind: "open-project"; resolvedPath: string } {
const program = createCli();
const knownCommands = new Set(program.commands.map((command) => command.name()));
const invocation = classifyInvocation({
argv: input.argv,
knownCommands,
cwd: input.cwd,
});
if (invocation.kind === "open-project") {
return invocation;
}
const nodeArgv = input.nodeArgv ?? ["paseo", "paseo"];
const isOnboardRootFlag = invocation.argv[0] === "--relay" || invocation.argv[0] === "--no-relay";
let cliArgv = invocation.argv;
if (invocation.argv.length === 0) {
cliArgv = ["onboard"];
} else if (isOnboardRootFlag) {
cliArgv = ["onboard", ...invocation.argv];
}
return [...nodeArgv, ...cliArgv];
}
export async function runCli(argv: string[], options: RunCliOptions = {}): Promise<number> {
const parseArgv = createCliParseArgv({
argv,
cwd: options.cwd ?? process.cwd(),
nodeArgv: options.nodeArgv,
});
if (!Array.isArray(parseArgv)) {
await openDesktopWithProject(parseArgv.resolvedPath);
return typeof process.exitCode === "number" ? process.exitCode : 0;
}
const program = createCli();
await program.parseAsync(parseArgv, { from: "node" });
return typeof process.exitCode === "number" ? process.exitCode : 0;
}