diff --git a/agent/src/service/install.ts b/agent/src/service/install.ts index adae58e..8563098 100644 --- a/agent/src/service/install.ts +++ b/agent/src/service/install.ts @@ -11,7 +11,7 @@ * - FIX M-host-2service: base-app env (BIND_HOST/ALLOWED_ORIGINS/PORT/…) is routed to the * base-app unit ONLY; the agent unit (which supervises frpc) never carries it. */ -import { dirname } from 'node:path' +import { dirname, join } from 'node:path' import type { AgentConfig } from '../config/agentConfig.js' import { agentLabel, @@ -225,9 +225,15 @@ export async function installService( if (platform === 'launchd') { const baseAppPath = launchdPlistPath(deps.homedir(), baseAppLabel()) - deps.writeFile(baseAppPath, buildLaunchdPlist(baseAppExec, baseAppEnvWithPath, baseAppLabel())) + deps.writeFile( + baseAppPath, + buildLaunchdPlist(baseAppExec, baseAppEnvWithPath, baseAppLabel(), join(cfg.stateDir, 'base-app.log')), + ) const agentPath = launchdPlistPath(deps.homedir(), agentLabel()) - deps.writeFile(agentPath, buildLaunchdPlist([nodePath, bin, 'run'], agentEnv, agentLabel())) + deps.writeFile( + agentPath, + buildLaunchdPlist([nodePath, bin, 'run'], agentEnv, agentLabel(), join(cfg.stateDir, 'agent.log')), + ) for (const path of [baseAppPath, agentPath]) { const { cmd, args } = launchdLoadCommand(path) await deps.runCommand(cmd, args) diff --git a/agent/src/service/launchd.ts b/agent/src/service/launchd.ts index b4d1e76..772ca4b 100644 --- a/agent/src/service/launchd.ts +++ b/agent/src/service/launchd.ts @@ -78,6 +78,7 @@ export function buildLaunchdPlist( programArguments: readonly string[], env: ServiceEnv = {}, label: string = AGENT_LABEL, + logPath?: string, ): string { return [ '', @@ -91,6 +92,16 @@ export function buildLaunchdPlist( ' ', ' KeepAlive', ' ', + // launchd's default has no log sink (unlike systemd's journald), so a crashing unit is silent. + // Route stdout+stderr to a file so `pair --install` failures are diagnosable out of the box. + ...(logPath !== undefined + ? [ + ' StandardOutPath', + ` ${escapeXml(logPath)}`, + ' StandardErrorPath', + ` ${escapeXml(logPath)}`, + ] + : []), ...environmentVariablesBlock(env), '', '',