/** * Generate a macOS launchd plist to keep the Feishu bridge running. * * Usage: * FEISHU_APP_ID=cli_xxx node setup-service.mjs * * Then: * launchctl load ~/Library/LaunchAgents/com.clawdbot.feishu-bridge.plist */ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; const APP_ID = process.env.FEISHU_APP_ID; if (!APP_ID) { console.error('Please set FEISHU_APP_ID environment variable'); process.exit(1); } const HOME = os.homedir(); const NODE_PATH = process.execPath; // e.g. /opt/homebrew/bin/node const BRIDGE_PATH = path.resolve(import.meta.dirname, 'bridge.mjs'); const WORK_DIR = path.resolve(import.meta.dirname); const LABEL = 'com.clawdbot.feishu-bridge'; const SECRET_PATH = process.env.FEISHU_APP_SECRET_PATH || `${HOME}/.clawdbot/secrets/feishu_app_secret`; const plist = ` Label ${LABEL} ProgramArguments ${NODE_PATH} ${BRIDGE_PATH} WorkingDirectory ${WORK_DIR} RunAtLoad KeepAlive EnvironmentVariables HOME ${HOME} PATH /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin FEISHU_APP_ID ${APP_ID} FEISHU_APP_SECRET_PATH ${SECRET_PATH} StandardOutPath ${HOME}/.clawdbot/logs/feishu-bridge.out.log StandardErrorPath ${HOME}/.clawdbot/logs/feishu-bridge.err.log `; // Ensure logs dir fs.mkdirSync(`${HOME}/.clawdbot/logs`, { recursive: true }); const outPath = path.join(HOME, 'Library', 'LaunchAgents', `${LABEL}.plist`); fs.mkdirSync(path.dirname(outPath), { recursive: true }); fs.writeFileSync(outPath, plist); console.log(`✅ Wrote: ${outPath}`); console.log(); console.log('To start the service:'); console.log(` launchctl load ${outPath}`); console.log(); console.log('To stop:'); console.log(` launchctl unload ${outPath}`);