import { formatNodeServiceDescription } from "../daemon/constants.js"; import { resolveNodeProgramArguments } from "../daemon/program-args.js"; import { buildNodeServiceEnvironment } from "../daemon/service-env.js"; import { emitDaemonInstallRuntimeWarning, resolveDaemonInstallRuntimeInputs, resolveDaemonNodeBinDir, } from "./daemon-install-plan.shared.js"; import type { DaemonInstallWarnFn } from "./daemon-install-runtime-warning.js"; import type { NodeDaemonRuntime } from "./node-daemon-runtime.js"; export type NodeInstallPlan = { programArguments: string[]; workingDirectory?: string; environment: Record; description?: string; }; export async function buildNodeInstallPlan(params: { env: Record; host: string; port: number; tls?: boolean; tlsFingerprint?: string; nodeId?: string; displayName?: string; runtime: NodeDaemonRuntime; devMode?: boolean; nodePath?: string; warn?: DaemonInstallWarnFn; }): Promise { const { devMode, nodePath } = await resolveDaemonInstallRuntimeInputs({ env: params.env, runtime: params.runtime, devMode: params.devMode, nodePath: params.nodePath, }); const { programArguments, workingDirectory } = await resolveNodeProgramArguments({ host: params.host, port: params.port, tls: params.tls, tlsFingerprint: params.tlsFingerprint, nodeId: params.nodeId, displayName: params.displayName, dev: devMode, runtime: params.runtime, nodePath, }); await emitDaemonInstallRuntimeWarning({ env: params.env, runtime: params.runtime, programArguments, warn: params.warn, title: "Node daemon runtime", }); const environment = buildNodeServiceEnvironment({ env: params.env, // Match the gateway install path so supervised node services keep the chosen // node toolchain on PATH for sibling binaries like npm/pnpm when needed. extraPathDirs: resolveDaemonNodeBinDir(nodePath), }); const description = formatNodeServiceDescription({ version: environment.OPENCLAW_SERVICE_VERSION, }); return { programArguments, workingDirectory, environment, description }; }