Files
paseo/packages/cli/src/utils/command-options.ts
T
Mohamed Boudra 047f40e623 Install npm plugins and review source updates (#4975)
* feat(plugins): unify source installation and simplify plugin settings

* feat(plugins): install npm sources and review CLI updates

Treat install selectors as one-time choices. Keep source identity separate from the installed revision, and resolve ordinary updates from the current upstream default. npm only acquires directories; plugin loading remains independent of npm.

* fix(plugins): preserve CLI diagnostics and exercise reviewed updates

Move new source capability coverage to real browser journeys. Update the requirements regression to exercise preview and apply, and preserve the existing duplicate-selector diagnostic across positional option scopes.

* test(plugins): remove unused pending helper

* test(plugins): pack registry fixtures with the Windows command runner

* test(plugins): assert failed client contribution setup

* docs(plugins): consolidate guides and document npm publishing

* docs(plugins): introduce publishing choices before npm instructions

* test(plugins): own browser journey cleanup in a fixture

* feat(plugins): prepare scaffolded packages for publishing
2026-09-17 10:22:20 +02:00

60 lines
2.2 KiB
TypeScript

import type { Command } from "commander";
import { selectDaemonTarget } from "./daemon-target.js";
const JSON_OPTION_DESCRIPTION = "Output in JSON format";
const DAEMON_HOST_OPTION_DESCRIPTION =
"Explicit daemon endpoint: host:port, TCP, socket, SSH, or pairing URL (default: local home)";
const localCommands = new WeakSet<Command>();
export function addLocalDaemonOptions<T extends Command>(command: T): T {
localCommands.add(command);
command.option("--home <path>", "Local daemon home (default: ~/.paseo)");
return command;
}
export function collectMultiple(value: string, previous: string[]): string[] {
return previous.concat([value]);
}
export function addJsonOption<T extends Command>(command: T): T {
command.option("--json", JSON_OPTION_DESCRIPTION);
return command;
}
export function addDaemonHostOption<T extends Command>(command: T): T {
command.option("--host <host>", DAEMON_HOST_OPTION_DESCRIPTION);
if (!command.options.some((option) => option.long === "--home"))
command.option("--home <path>", "Select a local daemon home (default: ~/.paseo)");
return command;
}
export function addJsonAndDaemonHostOptions<T extends Command>(command: T): T {
return addDaemonHostOption(addJsonOption(command));
}
export function withGlobalOptions<Args extends unknown[], Result>(
handler: (...args: Args) => Result,
): (...args: Args) => Result {
return (...args) => {
const command = args.at(-1) as Command;
const mergedArgs = [...args];
const options = command.optsWithGlobals();
const selectors = { home: new Set<string>(), host: new Set<string>() };
for (let current: Command | null = command; current; current = current.parent) {
for (const key of ["home", "host"] as const) {
const value = current.opts()[key];
if (typeof value === "string") selectors[key].add(value);
}
}
for (const key of ["home", "host"] as const) {
if (selectors[key].size > 1)
throw { code: "TARGET_AMBIGUOUS", message: `Conflicting duplicate --${key} selectors.` };
}
const localOnly = localCommands.has(command);
options.daemonTarget = selectDaemonTarget(options, process.env, localOnly);
mergedArgs[mergedArgs.length - 2] = options;
return handler(...(mergedArgs as Args));
};
}