relife2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/cli.js +4778 -0
- package/dist/cli.js.map +7 -0
- package/package.json +39 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/config/jsloader.ts", "../src/daemon/client.ts", "../src/ipc/protocol.ts", "../src/util/fsx.ts", "../src/util/time.ts", "../src/daemon/base.ts", "../src/util/args.ts", "../src/commands/delete.ts", "../src/commands/describe.ts", "../src/commands/dev.ts", "../src/commands/doctor.ts", "../src/commands/find.ts", "../src/config/loader.ts", "../src/util/cron.ts", "../src/util/dotenv.ts", "../src/util/memory.ts", "../src/util/portable.ts", "../src/commands/flush.ts", "../src/commands/fromCaddy.ts", "../src/version.ts", "../src/commands/help.ts", "../src/commands/importpm2.ts", "../src/commands/inspectconfig.ts", "../src/commands/kill.ts", "../src/commands/list.ts", "../src/commands/logs.ts", "../src/commands/metrics.ts", "../src/commands/monit.ts", "../src/commands/ping.ts", "../src/commands/reload.ts", "../src/commands/restart.ts", "../src/commands/resurrect.ts", "../src/commands/rotate.ts", "../src/commands/save.ts", "../src/commands/start.ts", "../src/commands/startup.ts", "../src/commands/stop.ts", "../src/commands/upgrade.ts", "../src/commands/version.ts", "../src/daemon/daemon.ts", "../src/daemon/applog.ts", "../src/util/datefmt.ts", "../src/daemon/logger.ts", "../src/daemon/pm.ts", "../src/daemon/command.ts", "../src/daemon/memproc.ts", "../src/daemon/state.ts", "../src/daemon/transport.ts", "../src/cli.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\n/**\n * Loads a JS/TS config file regardless of the surrounding package.json\n * \"type\" field. PM2 configs in the wild are usually CommonJS `.js` files\n * living inside ESM packages (e.g. example/ecosystem.config.js here), so a\n * bare `import()` or `require()` alone would break.\n *\n * Strategy:\n * - `.mjs` -> ESM dynamic import (cache-busted with a `?t=` query)\n * - `.cjs` -> CJS require (cache-busted)\n * - `.js` -> sniff: CJS-looking content is force-compiled as CJS\n * (via Module#_compile under node), otherwise ESM first,\n * CJS on failure.\n */\nconst CJS_MARKER = /^\\s*(?:module\\.exports|exports\\.[\\w$])/m;\n\ninterface CjsModuleLike {\n exports: unknown;\n filename: string;\n paths: string[];\n _compile(source: string, filename: string): void;\n}\n\ninterface NodeModuleNamespace {\n Module: new (filename: string, parent: unknown) => CjsModuleLike;\n _nodeModulePaths(from: string): string[];\n}\n\nexport async function loadJsFile(file: string): Promise<unknown> {\n const ext = path.extname(file).toLowerCase();\n const source = fs.readFileSync(file, \"utf8\");\n\n if (ext === \".mjs\") return importFreshEs(file);\n if (ext === \".cjs\") return loadCjs(file, source);\n\n if (CJS_MARKER.test(source)) return loadCjs(file, source);\n try {\n return await importFreshEs(file);\n } catch {\n return loadCjs(file, source);\n }\n}\n\nfunction importFreshEs(file: string): Promise<unknown> {\n const url = `${pathToFileURL(file).href}?t=${Date.now()}`;\n return import(url).then((mod) => (mod.default ?? mod) as unknown);\n}\n\nfunction loadCjs(file: string, source: string): unknown {\n // Preferred: a fresh compile (no require-cache staleness between starts).\n // Works under node; covers `.js` CJS configs inside `type: module` packages.\n try {\n return compileCjs(file, source);\n } catch {\n // Fallback (e.g. bun): classic require.\n const require = createRequire(import.meta.url);\n try {\n return require(file);\n } catch (err) {\n throw new Error(`cannot load config '${file}': ${(err as Error).message}`);\n }\n }\n}\n\n/** Force-compiles as CommonJS ignoring package.json \"type\". Node-only fallback. */\nfunction compileCjs(file: string, source: string): unknown {\n const req = createRequire(import.meta.url);\n const nodeModule = req(\"node:module\") as unknown as NodeModuleNamespace;\n const mod = new nodeModule.Module(file, null);\n mod.filename = file;\n mod.paths = nodeModule._nodeModulePaths(path.dirname(file));\n mod._compile(source, file);\n return mod.exports;\n}\n", "import { spawn } from \"node:child_process\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport { PROTOCOL_VERSION, RpcError } from \"../ipc/protocol\";\nimport { readJsonFile } from \"../util/fsx\";\nimport { sleep } from \"../util/time\";\nimport { dataDir, defaultPort, runtimeDir } from \"./base\";\n\nconst CONNECT_TIMEOUT = 1500;\nconst CALL_TIMEOUT = 30_000;\n\n/** Connects to the daemon endpoint inside the runtime dir. */\nexport async function tryConnect(runtime: string): Promise<net.Socket | null> {\n const opts =\n process.platform === \"win32\"\n ? { host: \"127.0.0.1\", port: currentPort(runtime) }\n : { path: path.join(runtime, \"relife2.sock\") };\n return new Promise((resolve) => {\n const sock = net.connect(opts);\n const timer = setTimeout(() => {\n sock.destroy();\n resolve(null);\n }, CONNECT_TIMEOUT);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n resolve(sock);\n });\n sock.once(\"error\", () => {\n clearTimeout(timer);\n resolve(null);\n });\n });\n}\n\nfunction currentPort(runtime: string): number {\n const data = readJsonFile<number | { port?: number }>(path.join(runtime, \"daemon.port\"));\n if (typeof data === \"number\" && Number.isInteger(data)) return data;\n if (data !== null && typeof data === \"object\" && typeof data.port === \"number\") return data.port;\n return defaultPort(runtime);\n}\n\n/** NDJSON request/response client over the socket. */\nexport class RpcClient {\n private buffer = \"\";\n private nextId = 1;\n private readonly pending = new Map<\n number,\n { resolve: (v: unknown) => void; reject: (e: Error) => void; timer: NodeJS.Timeout }\n >();\n\n constructor(private readonly socket: net.Socket) {\n socket.setEncoding(\"utf8\");\n socket.on(\"data\", (d: string | Buffer) => this.onData(d));\n socket.on(\"close\", () => this.failAll(new Error(\"connection to daemon closed\")));\n socket.on(\"error\", () => this.failAll(new Error(\"connection to daemon failed\")));\n }\n\n call<T>(method: string, params?: unknown, timeoutMs = CALL_TIMEOUT): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const id = this.nextId++;\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`timeout waiting for daemon method '${method}'`));\n }, timeoutMs);\n this.pending.set(id, {\n resolve: (v) => resolve(v as T),\n reject,\n timer,\n });\n this.socket.write(`${JSON.stringify({ id, method, params })}\\n`);\n });\n }\n\n close(): void {\n try {\n this.socket.end();\n } catch {\n // ignore\n }\n }\n\n private onData(d: string | Buffer): void {\n const text = typeof d === \"string\" ? d : d.toString(\"utf8\");\n this.buffer += text;\n let idx = this.buffer.indexOf(\"\\n\");\n while (idx >= 0) {\n const line = this.buffer.slice(0, idx);\n this.buffer = this.buffer.slice(idx + 1);\n if (line.trim() !== \"\") this.onMessage(line);\n idx = this.buffer.indexOf(\"\\n\");\n }\n }\n\n private onMessage(line: string): void {\n let msg: {\n id?: unknown;\n ok?: unknown;\n result?: unknown;\n error?: { code?: string; message?: string };\n };\n try {\n msg = JSON.parse(line);\n } catch {\n return;\n }\n if (typeof msg.id !== \"number\") return;\n const entry = this.pending.get(msg.id);\n if (entry === undefined) return;\n this.pending.delete(msg.id);\n clearTimeout(entry.timer);\n if (msg.ok === true) {\n entry.resolve(msg.result);\n } else {\n entry.reject(new RpcError(msg.error?.code ?? \"ERROR\", msg.error?.message ?? \"daemon error\"));\n }\n }\n\n private failAll(err: Error): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timer);\n entry.reject(err);\n }\n this.pending.clear();\n }\n}\n\n/**\n * Ensures a daemon is running (spawning one if needed \u2014 never killing an\n * existing one), connects and validates the protocol version.\n */\nexport async function ensureDaemonClient(): Promise<RpcClient> {\n const runtime = runtimeDir();\n const data = dataDir();\n let sock = await tryConnect(runtime);\n if (sock === null) {\n spawnDaemon();\n for (let i = 0; i < 100 && sock === null; i++) {\n await sleep(100);\n sock = await tryConnect(runtime);\n }\n }\n if (sock === null) {\n throw new Error(\n `cannot connect to relife2 daemon (runtime: ${runtime}, data: ${data}); ` +\n `inspect ${path.join(data, \"logs\", \"daemon.log\")}`,\n );\n }\n const client = new RpcClient(sock);\n const ping = await client.call<{ version: string; protocol: number }>(\"ping\");\n if (ping.protocol !== PROTOCOL_VERSION) {\n client.close();\n throw new Error(\n `daemon protocol mismatch (daemon: ${ping.protocol}, cli: ${PROTOCOL_VERSION}); ` +\n `run 'relife2 kill' to stop the stale daemon`,\n );\n }\n return client;\n}\n\nexport function spawnDaemon(): void {\n const arg1 = process.argv[1];\n const isSingleBinary =\n arg1 === undefined ||\n (!arg1.endsWith(\".js\") && !arg1.endsWith(\".mjs\") && !arg1.endsWith(\".cjs\"));\n if (isSingleBinary) {\n const child = spawn(process.execPath, [], {\n env: { ...process.env, RELIFE2_DAEMON: \"1\" },\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n return;\n }\n const entry = path.resolve(arg1);\n const child = spawn(process.execPath, [entry], {\n env: { ...process.env, RELIFE2_DAEMON: \"1\" },\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n}\n", "/** Protocol version for CLI <-> daemon IPC. Bumped on incompatible changes. */\nexport const PROTOCOL_VERSION = 1;\n\nexport interface RpcRequest {\n id: number;\n method: string;\n params?: unknown;\n}\n\nexport interface RpcResponse {\n id: number;\n ok: boolean;\n result?: unknown;\n error?: { code: string; message: string };\n}\n\nexport class RpcError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n ) {\n super(message);\n }\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport function ensureDirSync(dir: string): void {\n fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function pathExists(p: string): boolean {\n try {\n fs.accessSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Atomic write: tmp file + fsync + rename. Never leaves a half-written file. */\nexport function atomicWriteFileSync(file: string, data: string): void {\n ensureDirSync(path.dirname(file));\n const tmp = `${file}.tmp-${process.pid}`;\n fs.writeFileSync(tmp, data, \"utf8\");\n try {\n const fd = fs.openSync(tmp, \"r\");\n try {\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n // fsync is best-effort (e.g. some filesystems)\n }\n fs.renameSync(tmp, file);\n}\n\nexport function readJsonFile<T>(file: string): T | null {\n if (!pathExists(file)) return null;\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\")) as T;\n } catch {\n return null;\n }\n}\n\n/** True if the pid exists on this host. */\nexport function isAlive(pid?: number): boolean {\n if (!pid || Number.isNaN(pid)) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === \"EPERM\";\n }\n}\n", "/**\n * Millisecond-based time strings like '10s', '500ms', '1m', '2h'; seconds by default.\n */\nexport function parseTime(v: number | string): number {\n if (typeof v === \"number\") return v;\n const s = String(v).trim();\n const m = /^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)?$/i.exec(s);\n if (!m || m[1] === undefined) {\n throw new Error(`invalid time string '${s}' (expected e.g. '500ms', '10s', '1m')`);\n }\n const n = Number.parseFloat(m[1]);\n const unit = (m[2] ?? \"s\").toLowerCase();\n const factor = { ms: 1, s: 1000, m: 60_000, h: 3_600_000, d: 86_400_000 }[unit];\n if (factor === undefined) throw new Error(`invalid time unit in '${s}'`);\n return Math.round(n * factor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n", "import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { isAlive, pathExists } from \"../util/fsx\";\n\nfunction envDir(name: string): string | null {\n const v = process.env[name]?.trim();\n return v ? path.resolve(v) : null;\n}\n\n/**\n * Where durable data lives (`state/`, `logs/`, `daemon.log`).\n * RELIFE2_DIR > $XDG_DATA_HOME/relife2 > ~/.relife2 (ADR-0006).\n */\nexport function dataDir(): string {\n const override = envDir(\"RELIFE2_DIR\");\n if (override !== null) return override;\n const xdg = envDir(\"XDG_DATA_HOME\");\n if (xdg !== null) return path.join(xdg, \"relife2\");\n return path.join(os.homedir(), \".relife2\");\n}\n\n/**\n * Where runtime files live (socket, lock, port file).\n * RELIFE2_DIR > $XDG_RUNTIME_DIR/relife2 > dataDir() (ADR-0006).\n * XDG_RUNTIME_DIR is tmpfs on Linux and wiped per-session \u2014 perfect for runtime.\n */\nexport function runtimeDir(): string {\n const override = envDir(\"RELIFE2_DIR\");\n if (override !== null) return override;\n const xdg = envDir(\"XDG_RUNTIME_DIR\");\n if (xdg !== null) return path.join(xdg, \"relife2\");\n return dataDir();\n}\n\nexport function lockPath(base: string): string {\n return path.join(base, \"daemon.lock\");\n}\n\nexport function unixSockPath(base: string): string {\n return path.join(base, \"relife2.sock\");\n}\n\nexport function portFilePath(base: string): string {\n return path.join(base, \"daemon.port\");\n}\n\n/** Deterministic loopback port derived from the base dir, so each dir = own daemon. */\nexport function defaultPort(base: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < base.length; i++) {\n h ^= base.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return 44720 + ((h >>> 0) % 1000);\n}\n\nexport interface LockHandle {\n release(): void;\n}\n\n/**\n * Exclusive single-daemon lock (belt & suspenders on top of the socket bind).\n * If another alive relife2 daemon holds it \u2014 returns null (we never kill it).\n */\nexport function acquireLock(base: string): LockHandle | null {\n fs.mkdirSync(base, { recursive: true });\n const file = lockPath(base);\n const payload = JSON.stringify({ app: \"relife2\", pid: process.pid, ts: Date.now() });\n try {\n fs.writeFileSync(file, payload, { flag: \"wx\" });\n return {\n release() {\n try {\n fs.unlinkSync(file);\n } catch {\n // already gone\n }\n },\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n\n // Lock exists: alive daemon or stale file from a crashed one.\n const stale = readLockInfo(file);\n if (stale !== null && isAlive(stale.pid)) {\n return null; // another daemon is running \u2014 do not touch it\n }\n try {\n fs.unlinkSync(file);\n } catch {\n // raced; someone else cleaned it\n }\n return acquireLock(base);\n}\n\nfunction readLockInfo(file: string): { pid: number } | null {\n if (!pathExists(file)) return null;\n try {\n const data = JSON.parse(fs.readFileSync(file, \"utf8\")) as { pid?: unknown };\n return typeof data.pid === \"number\" && Number.isInteger(data.pid) ? { pid: data.pid } : null;\n } catch {\n return null;\n }\n}\n", "/**\n * Minimal shell-like tokenizer for `args` given as a string in configs\n * (e.g. lorachi uses `args: \"./dist/server/entry.mjs\"`).\n * Handles single/double quotes and backslash escapes; keeps it dependency-free.\n */\nexport interface ParsedArgs {\n positionals: string[];\n opts: Map<string, string | boolean>;\n /** Args after `--` (app passthrough). */\n passthrough: string[];\n}\n\n/**\n * Tiny dependency-free CLI parser.\n * Long opts: `--x=v`, `--x v` (when `x` is listed in `valueOpts`), or boolean `--x`.\n * Short opts: `-x v` (value when the next arg is not a flag) or boolean `-x`.\n * `--` switches everything after it into `passthrough`.\n */\nexport function parseCliArgs(\n args: readonly string[],\n valueOpts: ReadonlySet<string> = new Set(),\n): ParsedArgs {\n const positionals: string[] = [];\n const opts = new Map<string, string | boolean>();\n const passthrough: string[] = [];\n let afterDashDash = false;\n let i = 0;\n while (i < args.length) {\n const a = args[i];\n if (a === undefined) break;\n if (afterDashDash) {\n passthrough.push(a);\n i += 1;\n continue;\n }\n if (a === \"--\") {\n afterDashDash = true;\n i += 1;\n continue;\n }\n if (a.startsWith(\"--\")) {\n const key = a.slice(2);\n const eq = key.indexOf(\"=\");\n if (eq >= 0) {\n opts.set(key.slice(0, eq), key.slice(eq + 1));\n i += 1;\n continue;\n }\n const next = args[i + 1];\n if (valueOpts.has(key) && next !== undefined && !next.startsWith(\"-\")) {\n opts.set(key, next);\n i += 2;\n } else {\n opts.set(key, true);\n i += 1;\n }\n continue;\n }\n if (a.startsWith(\"-\") && a.length >= 2) {\n const key = a.slice(1);\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith(\"-\")) {\n opts.set(key, next);\n i += 2;\n } else {\n opts.set(key, true);\n i += 1;\n }\n continue;\n }\n positionals.push(a);\n i += 1;\n }\n return { positionals, opts, passthrough };\n}\n\n/** Splits an `args: \"string\"` into tokens, honoring quotes and backslash escapes. */\nexport function splitArgs(input: string): string[] {\n const out: string[] = [];\n let cur = \"\";\n let quote: \"'\" | '\"' | null = null;\n let i = 0;\n while (i < input.length) {\n const c = input[i];\n if (c === undefined) break;\n if (quote === null) {\n if (c === '\"' || c === \"'\") {\n quote = c;\n } else if (c === \"\\\\\" && i + 1 < input.length) {\n cur += input[i + 1] ?? \"\";\n i += 1;\n } else if (c === \" \" || c === \"\\t\" || c === \"\\n\") {\n if (cur !== \"\") {\n out.push(cur);\n cur = \"\";\n }\n } else {\n cur += c;\n }\n } else if (c === quote) {\n quote = null;\n } else if (c === \"\\\\\" && quote === '\"' && i + 1 < input.length) {\n cur += input[i + 1] ?? \"\";\n i += 1;\n } else {\n cur += c;\n }\n i += 1;\n }\n if (cur !== \"\") out.push(cur);\n return out;\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 delete <name|all>\");\n return 1;\n }\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string }> }>(\"delete\", { name });\n for (const a of res.apps) {\n console.log(`ok deleted ${a.name}`);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 describe <name>\");\n return 1;\n }\n const client = await ensureDaemonClient();\n try {\n const rec = await client.call<unknown>(\"describe\", { name });\n console.log(JSON.stringify(rec, null, 2));\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { type ChildProcess, spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport path from \"node:path\";\nimport { parseCliArgs } from \"../util/args\";\n\nconst DEV_VALUE_OPTS = new Set([\"watch\", \"interpreter\", \"env\", \"name\", \"w\"]);\n\nfunction hasBun(): boolean {\n try {\n const r = spawnSync(\"bun\", [\"--version\"], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n return r.status === 0;\n } catch {\n return false;\n }\n}\n\nfunction isBunProject(cwd: string): boolean {\n let cur = path.resolve(cwd);\n const home = path.resolve(process.env.HOME ?? \"\");\n for (let i = 0; i < 12; i++) {\n if (fs.existsSync(path.join(cur, \"bun.lockb\")) || fs.existsSync(path.join(cur, \"bun.lock\")))\n return true;\n if (cur === home || cur === path.dirname(cur)) break;\n cur = path.dirname(cur);\n }\n return false;\n}\n\nfunction collectSubDirs(root: string): string[] {\n const out: string[] = [root];\n const stack = [root];\n while (stack.length > 0) {\n const dir = stack.pop()!;\n let entries: fs.Dirent[] = [];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n if (e.name === \"node_modules\" || e.name === \".git\" || e.name.startsWith(\".\")) continue;\n const p = path.join(dir, e.name);\n out.push(p);\n stack.push(p);\n }\n }\n return out;\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n printUsage();\n return 0;\n }\n\n const { positionals, opts, passthrough } = parseCliArgs(args, DEV_VALUE_OPTS);\n const scriptArg = positionals[0];\n if (!scriptArg) {\n console.error(\n \"usage: relife2 dev <script> [--watch <paths>] [--hot|--no-hot] [--interpreter <bin>] [-- --args...]\",\n );\n console.error(\" e.g. relife2 dev ./server.ts --watch ./src --hot\");\n console.error(\" e.g. relife2 dev ./app.js -- --port 3000\");\n return 1;\n }\n\n const script = path.resolve(scriptArg);\n if (!fs.existsSync(script)) {\n console.error(`dev: script not found: ${script}`);\n return 1;\n }\n const cwd = path.dirname(script);\n const useHot = opts.has(\"no-hot\") ? false : opts.has(\"hot\") ? true : undefined; // undefined = auto\n const watchRaw =\n (opts.get(\"watch\") as string | undefined) ?? (opts.get(\"w\") as string | undefined);\n const interpreterOpt = (opts.get(\"interpreter\") as string | undefined) ?? undefined;\n\n // Determine interpreter\n let interpreter: string | undefined = interpreterOpt;\n if (!interpreter) {\n const bunAvailable = hasBun();\n const looksBun = script.endsWith(\".ts\") || script.endsWith(\".tsx\") || isBunProject(cwd);\n if (bunAvailable && looksBun) interpreter = \"bun\";\n else interpreter = \"node\";\n }\n\n const isBun = interpreter === \"bun\";\n // Decide hot mode: explicit --hot, or auto if bun + ts\n const hot = useHot ?? (isBun && (script.endsWith(\".ts\") || script.endsWith(\".tsx\")));\n\n if (hot && !isBun) {\n console.error(\n \"dev: --hot requires bun interpreter (use --interpreter bun or run a .ts file with bun available)\",\n );\n return 1;\n }\n if (hot && isBun) {\n // Bun hot mode \u2014 let bun handle watching\n return runBunHot(script, cwd, passthrough, watchRaw);\n }\n // Manual watch+restart mode\n return runManualWatch(script, cwd, interpreter, passthrough, watchRaw);\n}\n\nasync function runBunHot(\n script: string,\n cwd: string,\n appArgs: readonly string[],\n watchRaw?: string,\n): Promise<number> {\n const extraWatch = watchRaw ? [\"--watch\"] : [];\n // bun --hot does HMR without restart; bun --watch does restart. Spec says --hot, so use --hot\n // If user gave --watch paths, also pass them via --watch? bun --hot already watches imports; extra --watch dir is not needed\n const bunArgs = [\"--hot\", script, ...appArgs];\n console.log(`dev (bun --hot): bun ${bunArgs.join(\" \")} [cwd ${cwd}]`);\n if (watchRaw)\n console.log(` note: --watch ${watchRaw} is ignored in --hot mode (bun watches imports)`);\n console.log(` press Ctrl+C to stop`);\n const child = spawn(\"bun\", bunArgs, { cwd, stdio: \"inherit\", env: process.env });\n return waitForExit(child);\n}\n\nasync function runManualWatch(\n script: string,\n cwd: string,\n interpreter: string,\n appArgs: readonly string[],\n watchRaw?: string,\n): Promise<number> {\n const targets: string[] = [];\n if (watchRaw) {\n for (const p of watchRaw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean)) {\n targets.push(path.resolve(cwd, p));\n }\n } else {\n targets.push(cwd);\n }\n\n console.log(\n `dev (watch): ${interpreter} ${path.basename(script)} ${appArgs.join(\" \")} [cwd ${cwd}]`,\n );\n console.log(` watching: ${targets.join(\", \")}`);\n console.log(` press Ctrl+C to stop`);\n\n let child: ChildProcess | null = null;\n let stopped = false;\n let restarting = false;\n let debounce: NodeJS.Timeout | null = null;\n\n const watchers: fs.FSWatcher[] = [];\n const startChild = () => {\n if (stopped) return;\n const cmd = interpreter === \"none\" ? script : interpreter;\n const cmdArgs = interpreter === \"none\" ? [...appArgs] : [script, ...appArgs];\n // node needs --loader for ts? let it fail naturally; bun would have used hot path\n child = spawn(cmd, cmdArgs, { cwd, stdio: \"inherit\", env: process.env, detached: false });\n child.on(\"exit\", (code, signal) => {\n if (stopped) return;\n if (restarting) {\n restarting = false;\n return;\n }\n // Unexpected exit \u2014 log and wait for file change to restart; don't hot-loop\n if (code !== null && code !== 0) {\n console.log(`dev: process exited with code ${code} \u2014 waiting for file change to restart`);\n } else if (signal) {\n console.log(`dev: process killed by ${signal} \u2014 waiting for file change`);\n } else {\n console.log(`dev: process exited \u2014 waiting for file change`);\n }\n });\n };\n\n const restart = () => {\n if (child?.pid && !child.killed) {\n restarting = true;\n try {\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n try {\n if (child?.pid && !child.killed) child.kill(\"SIGKILL\");\n } catch {}\n }, 1200);\n } catch {}\n child.once(\"exit\", () => {\n if (stopped) return;\n console.log(`dev: restarting\u2026`);\n startChild();\n });\n } else {\n console.log(`dev: restarting\u2026`);\n startChild();\n }\n };\n\n const scheduleRestart = (changedPath: string) => {\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(() => {\n console.log(`dev: change detected (${changedPath})`);\n restart();\n }, 200);\n };\n\n // Setup watchers\n for (const target of targets) {\n if (!fs.existsSync(target)) {\n console.error(`dev: watch path does not exist: ${target} \u2014 skipping`);\n continue;\n }\n const stat = fs.statSync(target);\n if (!stat.isDirectory()) {\n const dir = path.dirname(target);\n const base = path.basename(target);\n try {\n const w = fs.watch(dir, (_ev, filename) => {\n if (filename && filename !== base) return;\n scheduleRestart(target);\n });\n watchers.push(w);\n } catch (err) {\n console.error(`dev: cannot watch ${dir}: ${(err as Error).message}`);\n }\n continue;\n }\n if (process.platform === \"win32\" || process.platform === \"darwin\") {\n try {\n const w = fs.watch(target, { recursive: true }, () => scheduleRestart(target));\n watchers.push(w);\n } catch (err) {\n console.error(`dev: cannot watch ${target}: ${(err as Error).message}`);\n }\n } else {\n const dirs = collectSubDirs(target);\n for (const dir of dirs) {\n try {\n const w = fs.watch(dir, () => scheduleRestart(dir));\n watchers.push(w);\n } catch {}\n }\n }\n }\n\n const cleanup = () => {\n stopped = true;\n if (debounce) clearTimeout(debounce);\n for (const w of watchers)\n try {\n w.close();\n } catch {}\n if (child?.pid && !child.killed) {\n try {\n child.kill(\"SIGTERM\");\n } catch {}\n setTimeout(() => {\n try {\n if (child?.pid && !child.killed) child.kill(\"SIGKILL\");\n } catch {}\n }, 800);\n }\n };\n process.on(\"SIGINT\", () => {\n cleanup();\n setTimeout(() => process.exit(0), 400);\n });\n process.on(\"SIGTERM\", () => {\n cleanup();\n setTimeout(() => process.exit(0), 400);\n });\n\n startChild();\n\n // Keep dev alive until Ctrl+C\n return new Promise<number>((resolve) => {\n const onSig = () => resolve(0);\n process.once(\"SIGINT\", onSig);\n process.once(\"SIGTERM\", onSig);\n });\n}\n\nfunction waitForExit(child: ChildProcess): Promise<number> {\n return new Promise<number>((resolve) => {\n child.on(\"exit\", (code) => resolve(code ?? 0));\n child.on(\"error\", (err) => {\n console.error(`dev: failed to spawn: ${(err as Error).message}`);\n resolve(1);\n });\n process.on(\"SIGINT\", () => {\n try {\n child.kill(\"SIGTERM\");\n } catch {}\n setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {}\n }, 800);\n });\n process.on(\"SIGTERM\", () => {\n try {\n child.kill(\"SIGTERM\");\n } catch {}\n });\n });\n}\n\nfunction printUsage(): void {\n console.log(`relife2 dev \u2014 run a script with watch+restart (backlog, now ready)\n\nUsage: relife2 dev <script> [--watch <paths>] [--hot|--no-hot] [--interpreter <bin>] [-- --args...]\n\n <script> path to .js/.mjs/.ts file (resolved from cwd)\n --watch <paths> comma-separated paths to watch (default: script's directory)\n --hot force bun --hot (HMR, bun only)\n --no-hot force manual watch+restart even for bun/ts\n --interpreter <bin> node|bun|path (default: auto \u2014 bun if .ts or bun.lockb nearby)\n -- app args after -- are passed to the script\n\nMode:\n bun + --hot (default for .ts under bun) \u2192 bun --hot <script> (bun watches imports, instant HMR)\n otherwise \u2192 manual fs.watch + SIGTERM\u2192SIGKILL restart (works with node/bun/java\u2026)\n\nExamples:\n relife2 dev ./server.ts\n relife2 dev ./app.js --watch ./src,./config\n relife2 dev ./bot.ts --no-hot --watch ./src\n relife2 dev ./main.js -- --port 3000\n`);\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\ninterface DoctorIssue {\n severity: \"ok\" | \"warn\" | \"error\";\n code: string;\n message: string;\n}\n\ninterface DoctorReport {\n checks: Array<{ name: string; ok: boolean; issues: DoctorIssue[] }>;\n summary: { total: number; errors: number; warnings: number; ok: number };\n}\n\n/**\n * Runs a local integrity check on the running daemon.\n * Reports: daemon liveness, lock consistency, state file integrity,\n * orphan processes, transport health \u2014 without touching anything.\n */\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const report = await client.call<DoctorReport>(\"doctor\", {});\n let hadErrors = false;\n for (const check of report.checks) {\n const icon = check.ok ? \"\u2713\" : \"\u2717\";\n console.log(`${icon} ${check.name}`);\n for (const issue of check.issues) {\n const prefix =\n issue.severity === \"error\"\n ? \" \u26A0 ERROR\"\n : issue.severity === \"warn\"\n ? \" \u26A0 WARN \"\n : \" \u2713 OK \";\n console.log(`${prefix} [${issue.code}] ${issue.message}`);\n if (issue.severity === \"error\") hadErrors = true;\n }\n }\n console.log(\"---\");\n console.log(\n `checks: ${report.summary.total} total, ${report.summary.ok} ok, ${report.summary.warnings} warnings, ${report.summary.errors} errors`,\n );\n return hadErrors ? 1 : 0;\n } finally {\n client.close();\n }\n}\n", "import * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { loadConfigFile, looksLikeConfigFile } from \"../config/loader\";\nimport { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nconst VALUE_OPTS = new Set([\"root\", \"depth\"]);\n\nconst IGNORED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".hg\",\n \".svn\",\n \"vendor\",\n \".next\",\n \".output\",\n \"dist\",\n \"build\",\n \"target\",\n \"__pycache__\",\n \".cache\",\n \".pnpm\",\n \".yarn\",\n \".turbo\",\n \".parcel-cache\",\n \"Library\",\n \"AppData\",\n \".local\", // broad but contains share/nvm etc \u2014 scanning it is expensive\n \"proc\",\n \"sys\",\n \"dev\",\n]);\n\ninterface FoundEntry {\n path: string;\n apps: string[];\n error?: string;\n warnings: string[];\n}\n\nfunction findConfigs(root: string, maxDepth: number): string[] {\n const out: string[] = [];\n // stack of {dir, depth}\n const stack: Array<{ dir: string; depth: number }> = [{ dir: root, depth: 0 }];\n const visited = new Set<string>();\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur === undefined) break;\n const { dir, depth } = cur;\n if (depth > maxDepth) continue;\n // avoid symlink loops via realpath\n let real: string;\n try {\n real = fs.realpathSync(dir);\n } catch {\n continue;\n }\n if (visited.has(real)) continue;\n visited.add(real);\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n\n for (const ent of entries) {\n const full = path.join(dir, ent.name);\n // file match\n if (ent.isFile() && looksLikeConfigFile(ent.name)) {\n out.push(full);\n continue;\n }\n if (!ent.isDirectory()) continue;\n // skip ignored\n if (IGNORED_DIRS.has(ent.name)) continue;\n // skip hidden generally? but keep .config dirs? ignore dotfiles except maybe? Skip dot dirs except we already skipped .git/.cache etc \u2014 keep others\n if (ent.name.startsWith(\".\") && ![\".config\"].includes(ent.name)) {\n // allow .config but skip .vscode, .idea etc\n if ([\".vscode\", \".idea\", \".github\", \".husky\"].includes(ent.name)) continue;\n // still skip most hidden to avoid scanning .local etc already handled; but be conservative: skip all dot dirs at top levels to speed up\n if (depth < 2) continue;\n }\n // symlink dir: don't follow to avoid loops, unless it's a config dir? skip\n if (ent.isSymbolicLink()) continue;\n // depth check before push\n if (depth + 1 <= maxDepth) stack.push({ dir: full, depth: depth + 1 });\n }\n }\n return out;\n}\n\nasync function enrich(found: string[]): Promise<FoundEntry[]> {\n const entries: FoundEntry[] = [];\n for (const p of found) {\n try {\n const loaded = await loadConfigFile(p);\n entries.push({ path: p, apps: loaded.apps.map((a) => a.name), warnings: loaded.warnings });\n } catch (err) {\n entries.push({ path: p, apps: [], error: (err as Error).message, warnings: [] });\n }\n }\n return entries;\n}\n\nfunction relToRoot(p: string, root: string): string {\n const rel = path.relative(root, p);\n return rel === \"\" ? path.basename(p) : rel;\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals, opts } = parseCliArgs(args, VALUE_OPTS);\n\n const wantsStart = positionals[0] === \"start\" || opts.has(\"start\");\n const jsonMode = opts.has(\"json\");\n const allFlag = opts.has(\"all\");\n\n let root = opts.get(\"root\") as string | undefined;\n if (root === undefined) {\n if (allFlag) {\n root = process.platform === \"win32\" ? path.parse(process.cwd()).root : \"/\";\n } else {\n root = os.homedir() || process.cwd();\n }\n }\n root = path.resolve(root);\n\n let depth = 6;\n const depthRaw = opts.get(\"depth\") as string | undefined;\n if (depthRaw !== undefined) {\n const n = Number(depthRaw);\n if (!Number.isFinite(n) || n < 1 || n > 20) {\n console.error(`find: --depth must be 1..20, got '${depthRaw}'`);\n return 1;\n }\n depth = Math.round(n);\n }\n if (allFlag) depth = Math.max(depth, 8);\n\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n console.error(`find: root '${root}' does not exist or is not a directory`);\n return 1;\n }\n\n if (!jsonMode) console.log(`relife2 find \u2014 scanning ${root} (depth ${depth}) \u2026`);\n const t0 = Date.now();\n const foundPaths = findConfigs(root, depth);\n foundPaths.sort();\n const enriched = await enrich(foundPaths);\n const dt = Date.now() - t0;\n\n // daemon state for status column\n let running = new Set<string>();\n try {\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string }> }>(\"list\");\n running = new Set(res.apps.map((a) => a.name));\n // also handle instance suffix groups: if scale:0 running, then base \"scale\" is considered running\n for (const n of [...running]) {\n const base = n.split(\":\")[0];\n if (base !== undefined) running.add(base as string);\n }\n } finally {\n client.close();\n }\n } catch {\n // daemon not running \u2014 treat all as not running\n }\n\n // Build display rows\n const rows = enriched.map((e) => {\n const isError = e.error !== undefined;\n const statuses =\n e.apps.length === 0\n ? isError\n ? \"error\"\n : \"empty\"\n : e.apps.every((n) => running.has(n) || running.has(n.split(\":\")[0] as string))\n ? \"running\"\n : e.apps.some((n) => running.has(n))\n ? \"partial\"\n : \"stopped\";\n return { ...e, statuses };\n });\n\n if (jsonMode) {\n const jsonOut = rows.map((r) => ({\n path: r.path,\n rel: relToRoot(r.path, root as string),\n apps: r.apps,\n status: r.statuses,\n error: r.error,\n warnings: r.warnings,\n }));\n console.log(\n JSON.stringify({ root, depth, count: rows.length, tookMs: dt, configs: jsonOut }, null, 2),\n );\n } else {\n if (rows.length === 0) {\n console.log(`No configs found under ${root} (pattern *.config.{js,cjs,mjs,json,ts})`);\n console.log(`Hints: try --root <dir> --depth 8, or --all for full scan`);\n return 0;\n }\n console.log(`Found ${rows.length} config(s) in ${dt}ms:\\n`);\n // Compute column widths\n const rels = rows.map((r) => relToRoot(r.path, root as string));\n const maxRel = Math.max(12, ...rels.map((s) => s.length), 20);\n const maxApps = Math.max(4, ...rows.map((r) => r.apps.join(\",\").length), 12);\n console.log(`${\"path\".padEnd(maxRel)} ${\"apps\".padEnd(maxApps)} status notes`);\n console.log(`${\"-\".repeat(maxRel)} ${\"-\".repeat(maxApps)} ------ -----`);\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i] as FoundEntry & { statuses: string };\n const rel = rels[i] as string;\n const appsStr = r.apps.join(\",\") || (r.error ? \"!\" : \"-\");\n const note = r.error\n ? r.error.slice(0, 80)\n : r.warnings.length > 0\n ? (r.warnings[0]?.slice(0, 60) ?? \"\")\n : \"\";\n let line = `${rel.padEnd(maxRel)} ${appsStr.padEnd(maxApps)} ${r.statuses.padEnd(6)} ${note}`;\n if (r.statuses === \"running\") line = `\\x1b[32m${line}\\x1b[0m`;\n else if (r.statuses === \"error\") line = `\\x1b[31m${line}\\x1b[0m`;\n else if (r.statuses === \"stopped\") line = `\\x1b[90m${line}\\x1b[0m`;\n console.log(line);\n }\n console.log(`\\nTip: relife2 find start --root ${root} \u2192 start all stopped configs`);\n console.log(` relife2 find --json | jq . \u2192 scripting`);\n }\n\n if (!wantsStart) return 0;\n\n // --- start mode: launch every stopped/error-free config ---\n const toStart = rows.filter(\n (r) =>\n r.error === undefined &&\n r.apps.length > 0 &&\n r.statuses !== \"running\" &&\n r.statuses !== \"partial\",\n );\n if (toStart.length === 0) {\n if (!jsonMode)\n console.log(\"\\nNothing to start \u2014 all found configs are already running or broken.\");\n return 0;\n }\n if (!jsonMode) console.log(`\\nStarting ${toStart.length} config(s) not yet running\u2026\\n`);\n const client = await ensureDaemonClient();\n try {\n let started = 0;\n let failed = 0;\n for (const r of toStart) {\n try {\n const res = await client.call<{\n apps: Array<{ name: string; status: string; pid?: number; message?: string }>;\n warnings?: string[];\n }>(\"start\", {\n target: { type: \"config\", path: r.path },\n });\n for (const w of res.warnings ?? []) console.error(`warning ${path.basename(r.path)}: ${w}`);\n for (const a of res.apps) {\n if (a.status === \"errored\") {\n console.error(`x ${a.name} (${path.basename(r.path)}): ${a.message ?? \"failed\"}`);\n failed++;\n } else {\n console.log(\n `ok ${a.name}: ${a.status}${a.pid !== undefined ? ` (pid ${a.pid})` : \"\"} \u2190 ${relToRoot(r.path, root as string)}`,\n );\n if (!a.message?.includes(\"already\")) started++;\n }\n }\n } catch (err) {\n console.error(`x ${path.basename(r.path)}: ${(err as Error).message}`);\n failed++;\n }\n }\n if (!jsonMode)\n console.log(\n `\\nDone: started ${started}, failed ${failed}, skipped ${rows.length - toStart.length} already running`,\n );\n return failed > 0 ? 1 : 0;\n } finally {\n client.close();\n }\n}\n", "import * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { ExecMode, NormalizedApp } from \"../types\";\nimport { splitArgs } from \"../util/args\";\nimport { parseCron } from \"../util/cron\";\nimport { parseDotenv } from \"../util/dotenv\";\nimport { parseMemory } from \"../util/memory\";\nimport { fixCwd, fixScript } from \"../util/portable\";\nimport { parseTime } from \"../util/time\";\nimport { loadJsFile } from \"./jsloader\";\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nconst KNOWN_KEYS = new Set([\n \"name\",\n \"script\",\n \"args\",\n \"interpreter\",\n \"cwd\",\n \"env\",\n \"autorestart\",\n \"max_restarts\",\n \"restart_delay\",\n \"min_uptime\",\n \"kill_timeout\",\n \"instances\",\n \"exec_mode\",\n // M2: logging + env_file + wait_ready (+ pm2 aliases)\n \"out_file\",\n \"output\",\n \"error_file\",\n \"err_file\",\n \"merge_logs\",\n \"merge\",\n \"time\",\n \"timestamp\",\n \"log_date_format\",\n \"wait_ready\",\n \"env_file\",\n // M4: memory\n \"max_memory_restart\",\n // M5: scheduling + watch\n \"cron_restart\",\n \"watch\",\n \"watch_delay\",\n]);\n\n/** Fields that are still warned for future milestones. */\nconst LATER_KEYS: Record<string, string> = {\n user: \"M6\",\n group: \"M6\",\n uid: \"M6\",\n gid: \"M6\",\n};\n\nconst CONFIG_FILE_RE =\n /^(?:(?:ecosystem|pm2|relife2)[\\w.-]*|[\\w.-]*?)\\.config\\.(?:c?js|mjs|json|ts)$/i;\n\nexport function looksLikeConfigFile(file: string): boolean {\n return CONFIG_FILE_RE.test(path.basename(file));\n}\n\n/** Tries to find a default config in cwd: relife2.config.* \u2192 ecosystem.config.* */\nexport function findDefaultConfig(cwd: string): string | null {\n const candidates = [\n \"relife2.config.ts\",\n \"relife2.config.js\",\n \"relife2.config.cjs\",\n \"relife2.config.mjs\",\n \"relife2.config.json\",\n \"ecosystem.config.js\",\n \"ecosystem.config.cjs\",\n \"ecosystem.config.mjs\",\n \"ecosystem.config.json\",\n \"pm2.config.js\",\n \"pm2.config.cjs\",\n ];\n for (const name of candidates) {\n const full = path.join(cwd, name);\n if (fs.existsSync(full)) return full;\n }\n return null;\n}\n\nexport interface LoadedConfig {\n apps: NormalizedApp[];\n warnings: string[];\n}\n\n/** Loads an ecosystem-style config file (.js/.cjs/.mjs/.json/.ts). */\nexport async function loadConfigFile(\n filePath: string,\n opts?: { envName?: string },\n): Promise<LoadedConfig> {\n const ext = path.extname(filePath).toLowerCase();\n let exported: unknown;\n if (ext === \".json\") {\n exported = JSON.parse(fs.readFileSync(filePath, \"utf8\")) as unknown;\n } else if (ext === \".ts\") {\n exported = await loadTsFile(filePath);\n } else {\n exported = await loadJsFile(filePath);\n if (typeof exported === \"function\") {\n exported = await (exported as () => unknown)();\n }\n if (exported instanceof Promise) exported = await exported;\n }\n\n return normalizeExported(exported, path.dirname(filePath), opts);\n}\n\nasync function loadTsFile(file: string): Promise<unknown> {\n try {\n const { pathToFileURL } = await import(\"node:url\");\n const url = `${pathToFileURL(file).href}?t=${Date.now()}`;\n const mod = (await import(url)) as { default?: unknown };\n return (mod.default ?? mod) as unknown;\n } catch {\n const raw = fs.readFileSync(file, \"utf8\");\n const stripped = raw\n .replace(/^\\s*import\\s+type\\s+.*$/gm, \"\")\n .replace(/:\\s*[\\w<>[\\]|&\\s,?]+(?=[=;,\\n)}])/g, \"\")\n .replace(/\\s+as\\s+const/g, \"\");\n const tmp = `${file}.tmp.cjs`;\n try {\n fs.writeFileSync(tmp, stripped, \"utf8\");\n const { loadJsFile: lf } = await import(\"./jsloader\");\n return await lf(tmp);\n } finally {\n try {\n fs.unlinkSync(tmp);\n } catch {}\n }\n }\n}\n\nexport function normalizeExported(\n exported: unknown,\n sourceDir: string,\n opts?: { envName?: string },\n): LoadedConfig {\n let rawApps: unknown;\n if (Array.isArray(exported)) {\n rawApps = exported;\n } else if (exported !== null && typeof exported === \"object\") {\n rawApps = (exported as Record<string, unknown>).apps;\n }\n if (!Array.isArray(rawApps) || rawApps.length === 0) {\n throw new ConfigError(\"config must export { apps: [...] } with at least one app\");\n }\n\n const warnings: string[] = [];\n const apps = rawApps.map((raw, i) => normalizeApp(raw, sourceDir, warnings, i, opts?.envName));\n return { apps, warnings };\n}\n\nfunction normalizeApp(\n raw: unknown,\n sourceDir: string,\n warnings: string[],\n index: number,\n envName?: string,\n): NormalizedApp {\n if (raw === null || typeof raw !== \"object\") {\n throw new ConfigError(`apps[${index}] must be an object`);\n }\n const input = raw as Record<string, unknown>;\n\n // Collect env profile keys (env_xxx) before warning loop \u2014 they are handled\n const envProfiles: Record<string, Record<string, string>> = {};\n for (const key of Object.keys(input)) {\n if (key.startsWith(\"env_\")) {\n const profile = key.slice(4);\n const val = input[key];\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(val as Record<string, unknown>)) {\n out[k] = v === undefined || v === null ? \"\" : String(v);\n }\n envProfiles[profile] = out;\n }\n }\n }\n\n for (const key of Object.keys(input)) {\n if (KNOWN_KEYS.has(key)) continue;\n if (key.startsWith(\"env_\")) continue; // handled as profile\n const later = LATER_KEYS[key];\n if (later !== undefined) {\n warnings.push(`apps[${index}] '${key}' is ignored until milestone ${later} (TODO.md \u00A75)`);\n } else {\n warnings.push(`apps[${index}] unknown field '${key}' is ignored`);\n }\n }\n\n const scriptRaw = input.script;\n if (typeof scriptRaw !== \"string\" || scriptRaw === \"\") {\n throw new ConfigError(`apps[${index}] requires a string 'script'`);\n }\n\n // instances: number, string number, or \"max\"\n const instances = parseInstances(input.instances, index);\n const execMode = parseExecMode(input.exec_mode, index);\n\n const rawCwd = typeof input.cwd === \"string\" ? input.cwd : undefined;\n const cwdRaw = path.resolve(sourceDir, rawCwd ?? \".\");\n const cwdFix = fixCwd(cwdRaw, sourceDir);\n const cwd = cwdFix.path;\n if (cwdFix.fixed && cwdFix.reason) warnings.push(cwdFix.reason);\n const hasSep = scriptRaw.includes(\"/\") || scriptRaw.includes(\"\\\\\");\n const isJsExt = /\\.(?:c?js|mjs|ts|mts|cts)$/i.test(scriptRaw);\n const scriptRawResolved = hasSep || isJsExt ? path.resolve(cwd, scriptRaw) : scriptRaw;\n let script = scriptRawResolved;\n // Only try to fix absolute scripts that look like filesystem paths\n if (path.isAbsolute(scriptRawResolved)) {\n const f = fixScript(scriptRawResolved, cwd, sourceDir);\n if (f.fixed) {\n warnings.push(f.reason ?? `script '${scriptRawResolved}' \u2192 '${f.path}'`);\n script = f.path;\n } else if (!fs.existsSync(scriptRawResolved) && f.reason) {\n // keep warning for stale script that couldn't be fixed \u2014 visible in inspect-config / start\n warnings.push(f.reason);\n }\n }\n\n const name =\n typeof input.name === \"string\" && input.name !== \"\" ? input.name : defaultName(script);\n\n // Base env + env_file + selected profile\n const env = normalizeEnv(input.env, warnings, index);\n\n // Apply selected env profile (envName from --env, or NODE_ENV)\n const selectedEnv = envName ?? process.env.NODE_ENV;\n if (selectedEnv !== undefined && selectedEnv !== \"\") {\n const profile = envProfiles[selectedEnv];\n if (profile !== undefined) {\n Object.assign(env, profile);\n } else if (envName !== undefined) {\n warnings.push(`apps[${index}] --env '${envName}' has no matching env_${envName} profile`);\n }\n }\n\n const envFile =\n typeof input.env_file === \"string\" && input.env_file !== \"\" ? input.env_file : undefined;\n if (envFile !== undefined) {\n const envPath = path.resolve(cwd, envFile);\n let parsed: Record<string, string> | null = null;\n if (fs.existsSync(envPath) && fs.statSync(envPath).isFile()) {\n try {\n parsed = parseDotenv(fs.readFileSync(envPath, \"utf8\"));\n } catch (err) {\n warnings.push(\n `apps[${index}] env_file '${envFile}' could not be read: ${(err as Error).message}`,\n );\n }\n }\n if (parsed === null) {\n warnings.push(`apps[${index}] env_file '${envFile}': ${envPath} not found; ignored`);\n } else {\n for (const [k, v] of Object.entries(parsed)) {\n if (!(k in env) && !(k in process.env)) env[k] = v;\n }\n }\n }\n\n return {\n name,\n script,\n args: normalizeArgs(input.args, index),\n interpreter: typeof input.interpreter === \"string\" ? input.interpreter : undefined,\n cwd,\n env,\n autorestart: input.autorestart !== false,\n maxRestarts: toInt(input.max_restarts, 15, \"max_restarts\", index),\n restartDelay: toInt(input.restart_delay, 0, \"restart_delay\", index),\n minUptime: parseTimeField(input.min_uptime, \"1s\", \"min_uptime\", index),\n killTimeout: toInt(input.kill_timeout, 1600, \"kill_timeout\", index),\n outFile: strOrUndef(input.out_file ?? input.output),\n errFile: strOrUndef(input.error_file ?? input.err_file),\n mergeLogs: input.merge_logs === true || input.merge === true,\n time: input.time === true || input.timestamp === true,\n logDateFormat: strOrUndef(input.log_date_format),\n waitReady: input.wait_ready === true,\n envFile,\n maxMemoryRestart: parseMemoryField(input.max_memory_restart, \"max_memory_restart\", index),\n cronRestart: parseCronField(input.cron_restart, \"cron_restart\", index),\n watch: parseWatchField(input.watch, \"watch\", index),\n watchDelay: toInt(input.watch_delay, 1000, \"watch_delay\", index),\n instances,\n execMode,\n envName: selectedEnv,\n sourceDir,\n };\n}\n\nfunction strOrUndef(v: unknown): string | undefined {\n return typeof v === \"string\" && v !== \"\" ? v : undefined;\n}\n\nexport function normalizeEnv(\n env: unknown,\n warnings: string[],\n index: number,\n): Record<string, string> {\n if (env === undefined || env === null) return {};\n if (typeof env !== \"object\" || Array.isArray(env)) {\n warnings.push(`apps[${index}] 'env' must be an object; ignoring`);\n return {};\n }\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(env as Record<string, unknown>)) {\n out[k] = v === undefined || v === null ? \"\" : String(v);\n }\n return out;\n}\n\nfunction normalizeArgs(args: unknown, index: number): string[] {\n if (args === undefined || args === null) return [];\n if (Array.isArray(args)) return args.map((a) => String(a));\n if (typeof args === \"string\") return splitArgs(args);\n throw new ConfigError(`apps[${index}] 'args' must be a string or string[]`);\n}\n\nfunction toInt(v: unknown, fallback: number, field: string, index: number): number {\n if (v === undefined || v === null) return fallback;\n const n = Number(v);\n if (!Number.isFinite(n)) throw new ConfigError(`apps[${index}] '${field}' must be a number`);\n return Math.max(0, Math.round(n));\n}\n\nfunction parseTimeField(v: unknown, fallback: string, field: string, index: number): number {\n if (v === undefined || v === null) return parseTime(fallback);\n try {\n return parseTime(v as number | string);\n } catch (err) {\n throw new ConfigError(`apps[${index}] '${field}': ${(err as Error).message}`);\n }\n}\n\nfunction parseMemoryField(v: unknown, field: string, index: number): number | undefined {\n if (v === undefined || v === null) return undefined;\n try {\n return parseMemory(v as number | string);\n } catch (err) {\n throw new ConfigError(`apps[${index}] '${field}': ${(err as Error).message}`);\n }\n}\n\nfunction parseCronField(v: unknown, field: string, index: number): string | undefined {\n if (v === undefined || v === null) return undefined;\n if (typeof v !== \"string\" || v.trim() === \"\") {\n throw new ConfigError(`apps[${index}] '${field}' must be a non-empty cron expression string`);\n }\n const trimmed = v.trim();\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5) {\n throw new ConfigError(\n `apps[${index}] '${field}': invalid cron expression '${v}' (expected 5 fields: 'min hour dom month dow')`,\n );\n }\n try {\n parseCron(trimmed);\n } catch (err) {\n throw new ConfigError(\n `apps[${index}] '${field}': invalid cron expression '${v}': ${(err as Error).message}`,\n );\n }\n return trimmed;\n}\n\nfunction parseWatchField(v: unknown, field: string, index: number): boolean | string[] | undefined {\n if (v === undefined || v === null) return undefined;\n if (v === false) return false;\n if (v === true) return true;\n if (Array.isArray(v)) {\n const paths = v.filter((p) => typeof p === \"string\" && p !== \"\");\n if (paths.length === 0) {\n throw new ConfigError(`apps[${index}] '${field}': array must contain at least one path`);\n }\n return paths as string[];\n }\n throw new ConfigError(`apps[${index}] '${field}' must be false, true, or an array of paths`);\n}\n\nfunction parseInstances(v: unknown, index: number): number {\n if (v === undefined || v === null) return 1;\n if (v === \"max\" || v === \"MAX\") return os.cpus().length || 1;\n const n = Number(v);\n if (!Number.isFinite(n) || n < 1) {\n throw new ConfigError(`apps[${index}] 'instances' must be a positive number or 'max'`);\n }\n return Math.max(1, Math.round(n));\n}\n\nfunction parseExecMode(v: unknown, index: number): ExecMode {\n if (v === undefined || v === null) return \"fork\";\n const s = String(v).toLowerCase();\n if (s === \"fork\" || s === \"fork_mode\") return \"fork\";\n if (s === \"cluster\" || s === \"cluster_mode\") return \"cluster\";\n throw new ConfigError(`apps[${index}] 'exec_mode' must be 'fork' or 'cluster'`);\n}\n\nfunction defaultName(script: string): string {\n const base = path.basename(script);\n return base.replace(/\\.(?:c?js|mjs|ts|mts|cts)$/i, \"\") || base;\n}\n\n/** Normalizes a bare `relife2 start script` invocation (with CLI-provided overrides). */\nexport function normalizeSingleApp(\n input: Record<string, unknown>,\n sourceDir: string,\n envName?: string,\n): { app: NormalizedApp; warnings: string[] } {\n const warnings: string[] = [];\n const effectiveEnv = (input._envName as string | undefined) ?? envName;\n const app = normalizeApp(input, sourceDir, warnings, 0, effectiveEnv);\n return { app, warnings };\n}\n", "/**\n * Zero-dependency cron expression parser (ADR-0002: no runtime deps).\n * Supports standard 5-field cron: minute hour day-of-month month day-of-week.\n * Each field supports: wildcard, exact value, comma list, range, step.\n * Does NOT support month names or day names or L/W/#.\n */\n\nconst FIELD_RANGES: readonly [\n readonly [number, number],\n readonly [number, number],\n readonly [number, number],\n readonly [number, number],\n readonly [number, number],\n] = [\n [0, 59], // minute\n [0, 23], // hour\n [1, 31], // day of month\n [1, 12], // month\n [0, 6], // day of week (0 = Sunday)\n] as const;\n\nfunction assertInRange(v: number, min: number, max: number, field: string): void {\n if (v < min || v > max) {\n throw new Error(`cron value ${v} out of range [${min}, ${max}] in field '${field}'`);\n }\n}\n\n/** Parses a single cron field into a Set of matching values. */\nfunction parseField(field: string, min: number, max: number): Set<number> {\n if (field === \"\") throw new Error(\"empty cron field\");\n const values = new Set<number>();\n for (const part of field.split(\",\")) {\n if (part === \"\") throw new Error(\"empty cron list element\");\n const stepMatch = /^(.+)\\/(\\d+)$/.exec(part);\n const step = stepMatch?.[2] !== undefined ? Number(stepMatch[2]) : 1;\n if (step <= 0 || !Number.isInteger(step)) throw new Error(`invalid cron step '${part}'`);\n const rangePart = stepMatch?.[1] !== undefined ? stepMatch[1] : part;\n\n if (rangePart === \"*\") {\n for (let v = min; v <= max; v += step) values.add(v);\n } else {\n const rangeMatch = /^(\\d+)-(\\d+)$/.exec(rangePart);\n if (rangeMatch !== null) {\n const start = Number(rangeMatch[1]);\n const end = Number(rangeMatch[2]);\n assertInRange(start, min, max, field);\n assertInRange(end, min, max, field);\n if (start > end) throw new Error(`invalid cron range '${rangePart}': start > end`);\n for (let v = start; v <= end; v += step) values.add(v);\n } else {\n const v = Number(rangePart);\n if (!Number.isInteger(v)) {\n throw new Error(`invalid cron field value '${rangePart}'`);\n }\n assertInRange(v, min, max, field);\n values.add(v);\n }\n }\n }\n if (values.size === 0) throw new Error(`cron field '${field}' produced no values`);\n return values;\n}\n\n/** Parses a full 5-field cron expression into per-field value sets. */\nexport function parseCron(\n expr: string,\n): [Set<number>, Set<number>, Set<number>, Set<number>, Set<number>] {\n const fields = expr.trim().split(/\\s+/);\n if (\n fields.length !== 5 ||\n fields[0] === undefined ||\n fields[1] === undefined ||\n fields[2] === undefined ||\n fields[3] === undefined ||\n fields[4] === undefined\n ) {\n throw new Error(`cron expression must have 5 fields, got ${fields.length}`);\n }\n return [\n parseField(fields[0], FIELD_RANGES[0][0], FIELD_RANGES[0][1]),\n parseField(fields[1], FIELD_RANGES[1][0], FIELD_RANGES[1][1]),\n parseField(fields[2], FIELD_RANGES[2][0], FIELD_RANGES[2][1]),\n parseField(fields[3], FIELD_RANGES[3][0], FIELD_RANGES[3][1]),\n parseField(fields[4], FIELD_RANGES[4][0], FIELD_RANGES[4][1]),\n ];\n}\n\n/** Returns true if the given date matches the cron expression. */\nexport function cronMatches(expr: string, date: Date): boolean {\n const [minutes, hours, dom, months, dow] = parseCron(expr);\n return (\n minutes.has(date.getMinutes()) &&\n hours.has(date.getHours()) &&\n dom.has(date.getDate()) &&\n months.has(date.getMonth() + 1) &&\n dow.has(date.getDay())\n );\n}\n\n/** Returns the next unix-ms timestamp at or after `from` that matches the cron expression. */\nexport function cronNext(expr: string, from: number): number {\n const [minutes, hours, dom, months, dow] = parseCron(expr);\n const d = new Date(from);\n d.setSeconds(0, 0);\n d.setMinutes(d.getMinutes() + 1); // start from next minute\n\n // Brute-force search up ahead (max ~366 days)\n for (let i = 0; i < 527_040; i++) {\n if (\n minutes.has(d.getMinutes()) &&\n hours.has(d.getHours()) &&\n dom.has(d.getDate()) &&\n months.has(d.getMonth() + 1) &&\n dow.has(d.getDay())\n ) {\n return d.getTime();\n }\n d.setMinutes(d.getMinutes() + 1);\n }\n return from;\n}\n", "/**\n * Minimal dotenv parser (no dependencies).\n * Supports `export ` prefixes, single/double-quoted values, escapes inside\n * double quotes, and trailing inline comments for unquoted values.\n */\nexport function parseDotenv(text: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const rawLine of text.split(/\\r?\\n/)) {\n let line = rawLine.trim();\n if (line === \"\" || line.startsWith(\"#\")) continue;\n if (line.startsWith(\"export \")) line = line.slice(\"export \".length).trim();\n\n const eq = line.indexOf(\"=\");\n if (eq < 0) continue;\n const key = line.slice(0, eq).trim();\n if (key === \"\") continue;\n let value = line.slice(eq + 1).trim();\n\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n const quote = value.charAt(0);\n const inner = value.slice(1, -1);\n value =\n quote === '\"'\n ? inner\n .replaceAll(\"\\\\n\", \"\\n\")\n .replaceAll(\"\\\\r\", \"\\r\")\n .replaceAll(\"\\\\t\", \"\\t\")\n .replaceAll('\\\\\"', '\"')\n .replaceAll(\"\\\\\\\\\", \"\\\\\")\n : inner;\n } else {\n const hash = value.indexOf(\" #\");\n if (hash >= 0) value = value.slice(0, hash).trim();\n }\n out[key] = value;\n }\n return out;\n}\n", "/**\n * Memory size strings like '256M', '1G', '512K', '1024'; bytes by default.\n */\nexport function parseMemory(v: number | string): number {\n if (typeof v === \"number\") return Math.max(0, Math.round(v));\n const s = String(v).trim();\n const m = /^(\\d+(?:\\.\\d+)?)\\s*(k|m|g|t)?b?$/i.exec(s);\n if (!m || m[1] === undefined) {\n throw new Error(`invalid memory string '${s}' (expected e.g. '256M', '1G', '512K')`);\n }\n const n = Number.parseFloat(m[1]);\n const unit = (m[2] ?? \"\").toLowerCase();\n const factor: Record<string, number> = {\n \"\": 1,\n k: 1024,\n m: 1_048_576,\n g: 1_073_741_824,\n t: 1_099_511_627_776,\n };\n const f = factor[unit];\n if (f === undefined) throw new Error(`invalid memory unit in '${s}'`);\n return Math.round(n * f);\n}\n", "import * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\n/** Checks if `p` is an existing directory. */\nfunction isDir(p: string): boolean {\n try {\n return fs.statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Checks if `p` is an existing file. */\nfunction isFile(p: string): boolean {\n try {\n return fs.statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Returns suffix after a home prefix like /home/debian/, /Users/vic/, C:\\Users\\vic\\ etc, or null. */\nfunction stripHomePrefix(p: string): string | null {\n // Unix: /home/<user>/rest or /Users/<user>/rest or /opt/<user>/rest ? treat /opt as home-like when homedir is /opt\n const m = p.match(/^\\/(?:home|Users|opt)\\/[^/\\\\]+[/\\\\](.*)$/);\n if (m?.[1] !== undefined) return m[1];\n // Windows with drive: C:/home/<user>/rest, C:/Users/<user>/rest, C:/opt/<user>/rest\n const dm = p.match(/^[A-Za-z]:[/\\\\]+(?:home|Users|opt)[/\\\\]+[^/\\\\]+[/\\\\]+(.*)$/i);\n if (dm?.[1] !== undefined) return dm[1].replaceAll(\"\\\\\", \"/\");\n // Windows: C:\\Users\\<user>\\rest or C:/Users/...\n const wm = p.match(/^[A-Za-z]:[\\\\/]+Users[\\\\/]+[^\\\\/]+[\\\\/]+(.*)$/i);\n if (wm?.[1] !== undefined) return wm[1].replaceAll(\"\\\\\", \"/\");\n return null;\n}\n\n/** Search under `root` for a file named `basename` up to `maxDepth` (BFS). Returns first match or null. */\nfunction searchByBasename(root: string, basename: string, maxDepth = 4): string | null {\n const queue: Array<{ dir: string; depth: number }> = [{ dir: root, depth: 0 }];\n const seen = new Set<string>();\n while (queue.length > 0) {\n const cur = queue.shift() as { dir: string; depth: number };\n if (cur.depth > maxDepth) continue;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(cur.dir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const e of entries) {\n const full = path.join(cur.dir, e.name);\n if (e.isFile() && e.name === basename) return full;\n if (e.isDirectory() && !e.isSymbolicLink()) {\n if (e.name === \"node_modules\" || e.name === \".git\") continue;\n const real = (() => {\n try {\n return fs.realpathSync(full);\n } catch {\n return full;\n }\n })();\n if (seen.has(real)) continue;\n seen.add(real);\n queue.push({ dir: full, depth: cur.depth + 1 });\n }\n }\n }\n return null;\n}\n\n/**\n * Try to fix a stale `cwd` that points at an old home (e.g. /home/debian/\u2026)\n * when the current machine uses /opt or /home/opt etc.\n * Returns a fixed path (may be same as input) + flag.\n */\nexport function fixCwd(\n staleCwd: string,\n sourceDir: string,\n): { path: string; fixed: boolean; reason?: string } {\n if (isDir(staleCwd)) return { path: staleCwd, fixed: false };\n const candidates: string[] = [];\n\n // 2) homedir replacement: strip old home prefix, rebase onto current homedir\n const tail = stripHomePrefix(staleCwd);\n if (tail !== null) {\n candidates.push(path.join(os.homedir(), tail));\n // also one level up from homedir (covers /home/debian \u2192 /opt case where homedir is /opt)\n candidates.push(path.join(path.dirname(os.homedir()), tail));\n // bare tail under sourceDir's parent\n candidates.push(path.join(path.dirname(sourceDir), tail));\n // project moved wholesale: stale home \u2192 use config dir itself if it looks stale\n // (only when stale is NOT already under current homedir)\n if (isDir(sourceDir) && !staleCwd.startsWith(os.homedir())) candidates.push(sourceDir);\n }\n\n // 3) project-basename heuristic: /home/debian/uwc/\u2026 + sourceDir=/opt/uwc \u2192 /opt/uwc/\u2026\n const proj = path.basename(sourceDir);\n if (proj) {\n const marker = `${path.sep}${proj}${path.sep}`;\n const altMarker = `/${proj}/`;\n const idx = staleCwd.includes(marker)\n ? staleCwd.lastIndexOf(marker)\n : staleCwd.lastIndexOf(altMarker);\n if (idx >= 0) {\n const suffix = staleCwd.slice(idx + proj.length + 2); // after /proj/\n candidates.push(path.join(sourceDir, suffix));\n candidates.push(path.join(path.dirname(sourceDir), proj, suffix));\n }\n }\n\n for (const c of candidates) {\n if (c && isDir(c))\n return { path: c, fixed: true, reason: `cwd '${staleCwd}' not found \u2192 auto-fixed to '${c}'` };\n }\n // fallback \u2014 return sourceDir even if not dir (will error later but with better message)\n return {\n path: staleCwd,\n fixed: false,\n reason: `cwd '${staleCwd}' not found and no auto-fix candidate exists`,\n };\n}\n\n/**\n * Try to fix a stale absolute script path (e.g. /home/debian/uwc/dist/app.js \u2192 /opt/uwc/dist/app.js).\n * `cwd` should already be the (possibly fixed) cwd. `sourceDir` is config dir.\n */\nexport function fixScript(\n staleScript: string,\n cwd: string,\n sourceDir: string,\n): { path: string; fixed: boolean; reason?: string } {\n if (isFile(staleScript)) return { path: staleScript, fixed: false };\n // relative scripts are resolved against cwd/sourceDir already by loader; if they were relative they are not \"stale\" here.\n // So staleScript is absolute and missing.\n\n const base = path.basename(staleScript);\n const candidates: string[] = [];\n\n // 1) basename directly under fixed cwd or sourceDir\n candidates.push(path.join(cwd, base));\n candidates.push(path.join(sourceDir, base));\n\n // 2) homedir rebasing\n const tail = stripHomePrefix(staleScript);\n if (tail !== null) {\n candidates.push(path.join(os.homedir(), tail));\n candidates.push(path.join(path.dirname(os.homedir()), tail));\n candidates.push(path.join(sourceDir, tail));\n // also try tail without first segment (project name) under sourceDir, e.g. uwc/dist/app.js \u2192 dist/app.js\n const tailParts = tail.split(\"/\");\n if (tailParts.length > 1) candidates.push(path.join(sourceDir, tailParts.slice(1).join(\"/\")));\n }\n\n // 3) project-basename suffix\n const proj = path.basename(sourceDir);\n if (proj) {\n const marker = `/${proj}/`;\n const idx = staleScript.lastIndexOf(marker);\n if (idx >= 0) {\n const suffix = staleScript.slice(idx + proj.length + 2);\n candidates.push(path.join(sourceDir, suffix));\n candidates.push(path.join(cwd, suffix));\n }\n }\n\n // 4) relative to fixed cwd if original was absolute but we can derive relative from old stale cwd\n // staleScript = /home/debian/uwc/dist/app.js , staleCwd was /home/debian/uwc \u2192 rel = dist/app.js\n // We don't have old cwd here, but we can try dist/app.js as last 2 segments:\n const parts = staleScript.split(/[/\\\\]/).filter(Boolean);\n if (parts.length >= 2) {\n const lastTwo = parts.slice(-2).join(path.sep); // dist/app.js\n candidates.push(path.join(sourceDir, lastTwo));\n candidates.push(path.join(cwd, lastTwo));\n }\n\n for (const c of candidates) {\n if (c && isFile(c))\n return {\n path: c,\n fixed: true,\n reason: `script '${staleScript}' not found \u2192 auto-fixed to '${c}'`,\n };\n }\n\n // 5) BFS search by basename under sourceDir (covers moved nested files)\n const found = searchByBasename(sourceDir, base, 4);\n if (found !== null)\n return {\n path: found,\n fixed: true,\n reason: `script '${staleScript}' not found \u2192 found '${found}' under '${sourceDir}'`,\n };\n\n // also try cwd\n if (cwd !== sourceDir) {\n const found2 = searchByBasename(cwd, base, 4);\n if (found2 !== null)\n return {\n path: found2,\n fixed: true,\n reason: `script '${staleScript}' not found \u2192 found '${found2}' under cwd`,\n };\n }\n\n return {\n path: staleScript,\n fixed: false,\n reason: `script '${staleScript}' not found and no auto-fix candidate exists`,\n };\n}\n\n/** Fix outFile/errFile/envFile parents \u2014 just ensure parent dir exists, rebasing homedir if needed. */\nexport function fixAuxPath(stalePath: string, cwd: string, sourceDir: string): string {\n if (path.isAbsolute(stalePath)) {\n if (fs.existsSync(path.dirname(stalePath))) return stalePath;\n const tail = stripHomePrefix(stalePath);\n if (tail !== null) {\n const cand = path.join(os.homedir(), tail);\n if (fs.existsSync(path.dirname(cand))) return cand;\n const cand2 = path.join(sourceDir, tail);\n if (fs.existsSync(path.dirname(cand2))) return cand2;\n // Fallback: even if parent doesn't exist yet, rebase to new project \u2014 ensureDir will create it\n // Prefer cwd-relative logs (stale = /home/debian/fake/logs/out.log \u2192 cwd/logs/out.log)\n const rel = tail.includes(\"/\") ? tail.split(\"/\").slice(-2).join(\"/\") : tail; // last 2 segments e.g. logs/out.log\n return path.join(cwd, rel);\n }\n // No home prefix \u2014 try project-basename suffix\n const proj = path.basename(sourceDir);\n if (proj) {\n const marker = `/${proj}/`;\n const idx = stalePath.lastIndexOf(marker);\n if (idx >= 0) {\n const suffix = stalePath.slice(idx + proj.length + 2);\n return path.join(sourceDir, suffix);\n }\n }\n // last resort: basename under cwd\n return path.join(cwd, path.basename(stalePath));\n } else {\n // relative \u2014 resolve against fixed cwd\n return path.resolve(cwd, stalePath);\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0] ?? \"all\";\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string; files: string[] }> }>(\"flush\", {\n name,\n });\n for (const a of res.apps) {\n console.log(`ok flushed ${a.name}${a.files.length > 0 ? \"\" : \" (no log files)\"}`);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst LOOPBACK_RE = /(?:127\\.0\\.0\\.1|localhost|::1):(\\d{2,5})/g;\nconst ENTRY_PATTERNS = [\n \".output/server/index.mjs\",\n \"dist/server/entry.mjs\",\n \"dist/index.mjs\",\n \".output/server/index.js\",\n \"dist/server/entry.js\",\n \"index.mjs\",\n \"index.js\",\n \"server.mjs\",\n \"server.js\",\n \"bot.js\",\n \"app.js\",\n \"main.js\",\n];\n\nfunction parseHint(s) {\n const out = {};\n for (const part of s.trim().split(/\\s+/)) {\n const eq = part.indexOf(\"=\");\n if (eq > 0) {\n const k = part.slice(0, eq).trim();\n const v = part\n .slice(eq + 1)\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\");\n if (k) out[k] = v;\n }\n }\n return out;\n}\n\nfunction sanitizeName(site, port) {\n let s = site.trim().split(\",\")[0].trim();\n s = s.replace(/^https?:\\/\\//, \"\");\n s = s.split(\":\")[0];\n s = s.split(\"/\")[0];\n if (s.startsWith(\"*.\")) s = s.slice(2);\n if (!s || s === \"*\" || s.startsWith(\":\")) return port ? `app-${port}` : \"app\";\n const label = s.split(\".\")[0];\n let name = label.replace(/[^a-zA-Z0-9_-]/g, \"-\").replace(/^-+|-+$/g, \"\");\n if (!name) name = \"app\";\n return name.toLowerCase();\n}\n\nfunction extractUpstreams(block) {\n const out = [];\n const seen = new Set();\n const lines = block.split(\"\\n\");\n for (const line of lines) {\n const t = line.trim();\n if (!t || t.startsWith(\"#\")) continue;\n if (!/reverse_proxy|php_fastcgi/.test(t)) continue;\n let m: RegExpExecArray | null;\n LOOPBACK_RE.lastIndex = 0;\n // biome-ignore lint/suspicious/noAssignInExpressions: idiomatic RegExp exec loop\n while ((m = LOOPBACK_RE.exec(t)) !== null) {\n const port = Number(m[1]);\n if (port < 1 || port > 65535) continue;\n const raw = m[0];\n if (seen.has(raw)) continue;\n seen.add(raw);\n const host = raw.split(\":\")[0];\n out.push({ host, port, raw });\n }\n }\n if (out.length === 0) {\n const blockLoopbacks = [...block.matchAll(LOOPBACK_RE)];\n for (const b of blockLoopbacks) {\n const raw = b[0];\n if (seen.has(raw)) continue;\n const idx = b.index ?? 0;\n const before = block.slice(Math.max(0, idx - 200), idx);\n if (!/reverse_proxy|php_fastcgi/.test(before)) continue;\n const port = Number(b[1]);\n if (port < 1 || port > 65535) continue;\n seen.add(raw);\n out.push({ host: raw.split(\":\")[0], port, raw });\n }\n }\n return out;\n}\n\nfunction parseCaddyfile(content) {\n const warnings = [];\n const sites = [];\n const lines = content.split(\"\\n\");\n let depth = 0;\n let pendingHint = null;\n let currentSite = null;\n let siteDepth = -1;\n for (let i = 0; i < lines.length; i++) {\n const rawLine = lines[i];\n const trimmed = rawLine.trim();\n if (trimmed.startsWith(\"#\")) {\n const hm = trimmed.match(/#\\s*relife2:\\s*(.*)/i);\n if (hm) pendingHint = parseHint(hm[1]);\n continue;\n }\n if (trimmed === \"\") continue;\n if (currentSite === null && depth === 0) {\n const braceIdx = rawLine.indexOf(\"{\");\n if (braceIdx !== -1) {\n const before = rawLine.slice(0, braceIdx).trim();\n const firstWord = before.split(/\\s+/)[0].toLowerCase();\n const isDirective = [\n \"handle\",\n \"handle_path\",\n \"route\",\n \"reverse_proxy\",\n \"php_fastcgi\",\n \"file_server\",\n \"encode\",\n \"header\",\n \"redir\",\n \"respond\",\n \"tls\",\n \"log\",\n \"import\",\n ].includes(firstWord);\n if (!isDirective && before !== \"\" && before !== \"*\") {\n const site = {\n label: before.split(\",\")[0].trim(),\n rawLabel: before,\n hint: pendingHint,\n block: \"\",\n upstreams: [],\n };\n pendingHint = null;\n currentSite = site;\n siteDepth = depth;\n sites.push(site);\n const open = (rawLine.match(/\\{/g) || []).length;\n const close = (rawLine.match(/\\}/g) || []).length;\n depth += open - close;\n const after = rawLine.slice(braceIdx + 1);\n if (after.trim() && !after.trim().startsWith(\"}\")) site.block += `${after}\\n`;\n continue;\n }\n } else {\n let j = i + 1;\n while (j < lines.length && lines[j].trim() === \"\") j++;\n if (j < lines.length && lines[j].trim().startsWith(\"{\")) {\n const before = trimmed;\n const firstWord = before.split(/\\s+/)[0].toLowerCase();\n const isDirective = [\"handle\", \"route\"].includes(firstWord);\n if (!isDirective && before !== \"\") {\n const site = {\n label: before.split(\",\")[0].trim(),\n rawLabel: before,\n hint: pendingHint,\n block: \"\",\n upstreams: [],\n };\n pendingHint = null;\n currentSite = site;\n siteDepth = depth;\n sites.push(site);\n continue;\n }\n }\n }\n }\n if (currentSite !== null) currentSite.block += `${rawLine}\\n`;\n const open = (rawLine.match(/\\{/g) || []).length;\n const close = (rawLine.match(/\\}/g) || []).length;\n depth += open - close;\n if (depth < 0) depth = 0;\n if (currentSite !== null && depth <= siteDepth) {\n currentSite = null;\n siteDepth = -1;\n }\n }\n for (const s of sites) s.upstreams = extractUpstreams(s.block);\n return { sites, warnings };\n}\n\nfunction findEntry(dir) {\n for (const pat of ENTRY_PATTERNS) {\n const p = path.join(dir, pat);\n if (fs.existsSync(p)) return { script: pat, exists: true };\n }\n return null;\n}\n\nfunction guessDir(site, _port, hint, caddyfileDir) {\n const warnings = [];\n if (hint?.dir) {\n const d = path.isAbsolute(hint.dir) ? hint.dir : path.resolve(caddyfileDir, hint.dir);\n return { dir: d, warnings };\n }\n const searchRoots = [];\n const homedir = os.homedir();\n if (homedir) searchRoots.push(homedir);\n if (caddyfileDir) searchRoots.push(caddyfileDir);\n if (caddyfileDir) searchRoots.push(path.resolve(caddyfileDir, \"..\"));\n const uniqRoots = [...new Set(searchRoots)].filter(Boolean);\n const siteName = sanitizeName(site);\n const candidates = [];\n if (homedir) candidates.push(path.join(homedir, siteName));\n if (homedir) candidates.push(path.join(homedir, siteName.split(\"-\")[0]));\n for (const r of uniqRoots) candidates.push(path.join(r, siteName));\n const rawDir = site.split(\".\")[0].replace(/[^a-zA-Z0-9_-]/g, \"\");\n if (rawDir && homedir) candidates.push(path.join(homedir, rawDir));\n for (const cand of candidates) {\n if (fs.existsSync(cand) && fs.statSync(cand).isDirectory()) {\n const e = findEntry(cand);\n if (e) return { dir: cand, warnings };\n }\n }\n const fallback = homedir\n ? path.join(homedir, siteName)\n : path.join(caddyfileDir || process.cwd(), siteName);\n warnings.push(\n `no existing dir found for ${site} \u2192 using fallback ${fallback} (create or set via '# relife2: dir=...')`,\n );\n return { dir: fallback, warnings };\n}\n\nexport async function run(args) {\n let caddyfilePath = null;\n let outPath = null;\n let dryRun = false;\n let withCaddy = false;\n let jsonOut = false;\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--dry-run\" || a === \"-n\") dryRun = true;\n else if (a === \"--with-caddy\") withCaddy = true;\n else if (a === \"--json\") jsonOut = true;\n else if (a === \"-o\" || a === \"--output\") {\n outPath = args[i + 1] ?? null;\n i++;\n } else if (a.startsWith(\"-o=\")) outPath = a.slice(3);\n else if (!a.startsWith(\"-\") && caddyfilePath === null) caddyfilePath = a;\n else if (a === \"--help\" || a === \"-h\") {\n printUsage();\n return 0;\n }\n }\n const candidates = [\n caddyfilePath,\n caddyfilePath ? null : \"./Caddyfile\",\n caddyfilePath ? null : \"Caddyfile\",\n caddyfilePath ? null : \"/etc/caddy/Caddyfile\",\n caddyfilePath ? null : path.join(os.homedir(), \"Caddyfile\"),\n ].filter(Boolean);\n let resolvedCaddy = null;\n let content = null;\n for (const cand of candidates) {\n const p = path.resolve(cand);\n if (fs.existsSync(p)) {\n resolvedCaddy = p;\n content = fs.readFileSync(p, \"utf8\");\n break;\n }\n }\n if (!resolvedCaddy || content === null) {\n console.error(`from-caddy: Caddyfile not found. Tried: ${candidates.join(\", \")}`);\n console.error(\n ` Usage: relife2 from-caddy [/path/to/Caddyfile] [-o relife2.config.cjs] [--dry-run]`,\n );\n return 1;\n }\n const caddyfileDir = path.dirname(resolvedCaddy);\n const { sites } = parseCaddyfile(content);\n if (sites.length === 0) {\n console.error(`from-caddy: no sites found in ${resolvedCaddy}`);\n console.error(` Is it a valid Caddyfile? Sites should look like 'example.com { ... }'`);\n return 1;\n }\n const planned = [];\n const nameCounts = new Map();\n const portCounts = new Map();\n const warnings = [];\n for (const site of sites) {\n if (site.upstreams.length === 0) {\n warnings.push(\n `site '${site.rawLabel}' has no reverse_proxy/php_fastcgi to loopback \u2014 static only, skipping`,\n );\n continue;\n }\n for (const up of site.upstreams) {\n const isLoopback = up.host === \"127.0.0.1\" || up.host === \"localhost\" || up.host === \"::1\";\n if (!isLoopback) {\n warnings.push(`upstream ${up.raw} for site '${site.rawLabel}' is not loopback \u2014 skipping`);\n continue;\n }\n const baseName = site.hint?.name ?? sanitizeName(site.label, up.port);\n const count = nameCounts.get(baseName) ?? 0;\n nameCounts.set(baseName, count + 1);\n let name = baseName;\n if (count > 0) {\n const suffix = String(up.port);\n name = `${baseName}-${suffix}`;\n const c2 = nameCounts.get(name) ?? 0;\n if (c2 > 0) name = `${baseName}-${suffix}-${c2}`;\n nameCounts.set(name, (nameCounts.get(name) ?? 0) + 1);\n }\n const pc = portCounts.get(up.port) ?? 0;\n portCounts.set(up.port, pc + 1);\n if (pc > 0)\n warnings.push(\n `duplicate upstream port ${up.port} for site '${site.rawLabel}' (also used elsewhere) \u2014 check for collision`,\n );\n const { dir, warnings: dirWarns } = guessDir(site.label, up.port, site.hint, caddyfileDir);\n warnings.push(...dirWarns);\n const entry = site.hint?.script ?? site.hint?.entry ?? null;\n let exists = false;\n let relScript = \"\";\n if (entry) {\n relScript = entry;\n exists = fs.existsSync(path.isAbsolute(entry) ? entry : path.join(dir, entry));\n if (!exists) warnings.push(`hint script '${entry}' for ${name} not found under ${dir}`);\n } else {\n const found = findEntry(dir);\n if (found) {\n relScript = found.script;\n exists = true;\n } else {\n relScript = \".output/server/index.mjs\";\n exists = false;\n warnings.push(\n `no entry found under ${dir} for ${name} \u2014 using placeholder '${relScript}'`,\n );\n }\n }\n let interpreter = site.hint?.interpreter;\n if (!interpreter) {\n if (relScript.endsWith(\".mjs\") || relScript.endsWith(\".ts\")) {\n const hasBun =\n fs.existsSync(path.join(dir, \"bun.lockb\")) || fs.existsSync(path.join(dir, \"bun.lock\"));\n if (hasBun) interpreter = \"bun\";\n }\n }\n const item = {\n name,\n site: site.rawLabel,\n upstream: up,\n dir,\n script: relScript,\n exists,\n hint: site.hint,\n warnings: [],\n };\n item._interpreter = interpreter;\n planned.push(item);\n }\n }\n if (withCaddy) {\n const caddyName = \"caddy\";\n if (!nameCounts.has(caddyName)) {\n const item = {\n name: caddyName,\n site: \"system\",\n upstream: { host: \"127.0.0.1\", port: 0, raw: \"caddy\" },\n dir: caddyfileDir,\n script: \"caddy\",\n exists: true,\n hint: null,\n warnings: [],\n };\n item._interpreter = \"none\";\n planned.push(item);\n }\n }\n if (planned.length === 0) {\n console.error(`from-caddy: no loopback upstreams found in ${resolvedCaddy}`);\n if (warnings.length) {\n console.error(\" warnings:\");\n for (const w of warnings) console.error(` - ${w}`);\n }\n console.error(\n \" Tip: add '# relife2: dir=/path/to/app name=myapp' above a site block to hint.\",\n );\n return 1;\n }\n if (jsonOut) {\n console.log(JSON.stringify({ caddyfile: resolvedCaddy, sites, planned, warnings }, null, 2));\n return 0;\n }\n if (dryRun) {\n console.log(`from-caddy \u2014 dry-run for ${resolvedCaddy}\\n`);\n console.log(`Sites: ${sites.length}, upstreams: ${planned.length}\\n`);\n console.log(\n `site upstream \u2192 app dir entry`,\n );\n console.log(\n `------------------------------------------------------------------------------------------------`,\n );\n for (const p of planned) {\n const siteCol = p.site.padEnd(30).slice(0, 30);\n const upCol = p.upstream.raw.padEnd(18).slice(0, 18);\n const appCol = p.name.padEnd(16).slice(0, 16);\n const dirCol = p.dir.padEnd(28).slice(0, 28);\n const entryCol = p.script + (p.exists ? \"\" : \" (missing)\");\n console.log(`${siteCol} ${upCol} \u2192 ${appCol} ${dirCol} ${entryCol}`);\n }\n if (warnings.length) {\n console.log(`\\nWarnings:`);\n for (const w of warnings) console.log(` - ${w}`);\n }\n console.log(\n `\\nWould write ${planned.length} app(s) to ${outPath ?? \"relife2.config.cjs (dry-run, no file written)\"}`,\n );\n console.log(`Run without --dry-run to generate.`);\n return 0;\n }\n const resolvedOut = path.resolve(outPath ?? \"relife2.config.cjs\");\n const appsCode = planned\n .map((p) => {\n const interp = p._interpreter;\n const isCaddy = p.name === \"caddy\";\n const env = isCaddy\n ? {}\n : { NODE_ENV: \"production\", HOST: \"127.0.0.1\", PORT: String(p.upstream.port) };\n const siteClean =\n (p.site.split(\",\")[0] ?? \"\")\n .trim()\n .replace(/^https?:\\/\\//, \"\")\n .split(\" \")[0] ?? \"\";\n if (!isCaddy && siteClean && siteClean !== \"*\") {\n if (siteClean.includes(\".\")) env.SITE_URL = `https://${siteClean}`;\n }\n const lines = [];\n lines.push(` {`);\n lines.push(` name: '${p.name.replace(/'/g, \"\\\\'\")}',`);\n if (isCaddy) {\n lines.push(` script: 'caddy',`);\n lines.push(\n ` args: ['run', '--config', '${resolvedCaddy.replace(/'/g, \"\\\\'\")}', '--adapter', 'caddyfile'],`,\n );\n lines.push(` cwd: '${p.dir.replace(/'/g, \"\\\\'\")}',`);\n lines.push(` interpreter: 'none',`);\n } else {\n const scriptEsc = p.script.replace(/'/g, \"\\\\'\");\n const dirEsc = p.dir.replace(/'/g, \"\\\\'\");\n lines.push(` script: ${JSON.stringify(p.script)},`);\n lines.push(` cwd: ${JSON.stringify(p.dir)},`);\n if (interp) lines.push(` interpreter: ${JSON.stringify(interp)},`);\n lines.push(` instances: 1,`);\n lines.push(` exec_mode: 'fork',`);\n lines.push(` autorestart: true,`);\n lines.push(` max_memory_restart: '512M',`);\n lines.push(` env: {`);\n for (const [k, v] of Object.entries(env))\n lines.push(` ${k}: '${String(v).replace(/'/g, \"\\\\'\")}',`);\n lines.push(` },`);\n lines.push(` out_file: ${JSON.stringify(`./logs/${p.name}-out.log`)},`);\n lines.push(` error_file: ${JSON.stringify(`./logs/${p.name}-err.log`)},`);\n lines.push(` merge_logs: true,`);\n lines.push(` time: true,`);\n }\n if (!p.exists && !isCaddy) {\n lines.push(` // TODO: entry '${p.script}' not found under ${p.dir}`);\n lines.push(` // checked: ${ENTRY_PATTERNS.join(\", \")}`);\n lines.push(` // fix: set correct 'script' or create placeholder, or add hint:`);\n lines.push(` // # relife2: dir=${p.dir} script=./your/entry.js`);\n }\n lines.push(` },`);\n return lines.join(\"\\n\");\n })\n .join(\"\\n\");\n const fileContent = `// Generated by relife2 from-caddy \u2014 ${new Date().toISOString()}\n// Source: ${resolvedCaddy}\n// Caddy handles TLS/static/proxy, relife2 supervises apps.\n// Review and adjust cwd/script/PORT before relife2 start.\nmodule.exports = {\n apps: [\n${appsCode}\n ]\n};\n`;\n fs.writeFileSync(resolvedOut, fileContent, \"utf8\");\n console.log(\n `from-caddy: parsed ${sites.length} site(s), ${planned.length} upstream(s) from ${resolvedCaddy}`,\n );\n for (const p of planned) {\n const status = p.exists ? \"found\" : \"missing\";\n console.log(\n ` - ${p.site} \u2192 ${p.upstream.raw} \u2192 app '${p.name}' @ ${p.dir} / ${p.script} [${status}]`,\n );\n }\n if (warnings.length) {\n console.log(`\\nWarnings:`);\n for (const w of warnings) console.log(` - ${w}`);\n }\n console.log(`\\nWrote ${resolvedOut} (${planned.length} app(s))`);\n console.log(\n `Next: relife2 inspect-config ${path.basename(resolvedOut)} \u2192 relife2 start ${path.basename(resolvedOut)}`,\n );\n return 0;\n}\n\nfunction printUsage() {\n console.log(`Usage: relife2 from-caddy [Caddyfile] [-o relife2.config.cjs] [--dry-run] [--json] [--with-caddy]\n\n Parses a Caddyfile, finds reverse_proxy upstreams to 127.0.0.1/localhost,\n and generates a relife2 config with one app per upstream.\n\n Options:\n Caddyfile Path to Caddyfile (default: ./Caddyfile, /etc/caddy/Caddyfile, ~/Caddyfile)\n -o, --output <file> Output config path (default: ./relife2.config.cjs)\n -n, --dry-run Show plan without writing file\n --json Output parsed sites/upstreams as JSON (for scripting)\n --with-caddy Also add Caddy itself as a managed app (interpreter: none)\n\n Hints:\n Add a comment above a site block to override detection:\n # relife2: dir=/home/debian/uwc name=uwc script=.output/server/index.mjs interpreter=bun\n\n Example:\n relife2 from-caddy /etc/caddy/Caddyfile --dry-run\n relife2 from-caddy -o relife2.config.cjs\n relife2 from-caddy --with-caddy -o relife2.config.cjs && relife2 start relife2.config.cjs\n`);\n}\n", "/** relife2 version. Keep in sync with package.json \"version\". */\nexport const VERSION = \"1.0.0\";\n", "import { VERSION } from \"../version\";\n\nexport const HELP_TEXT = `relife2 ${VERSION} \u2014 process manager for Node.js & Bun apps (PM2 alternative, done right)\n\nUsage: relife2 <command> [options]\n\nCommands:\n start <config|script> [--name <n>] [--env <env>] [--instances <n|max>] [--exec-mode <fork|cluster>] [-- --app-args...]\n Start all apps from a config, or one script (M1/M6).\n No args \u2192 auto-discovers relife2.config.{ts,js,cjs,mjs,json} or ecosystem.config.* in cwd.\n --env <name> Select env profile (merges env_<name> over env; e.g. env_production)\n --instances <n|max> Override instances count per app (max = cpu count)\n --exec-mode <mode> Override exec_mode (fork|cluster)\n stop <name|all> Gracefully stop app(s) (SIGTERM \u2192 kill_timeout \u2192 SIGKILL)\n restart <name|all> Stop and respawn app(s)\n reload <name|all> Zero-downtime reload (M6): graceful restart, sequentially per instance\n delete <name|all> Stop and forget app(s)\n list | ls | status Table of managed apps\n describe <name> Full state + resolved config of one app\n ping Show daemon status and protocol version\n logs <name> [--lines N] [-f]\n Print app log lines (tail; -f follows)\n flush [name|all] Empty the app log file(s)\n rotate [--max-size <bytes>] [--retain <n>] [name|all]\n Rotate log files exceeding the size threshold (M3)\n doctor Run integrity checks on the running daemon (M3)\n metrics Show daemon self-metrics + per-app summary (M3)\n monit [--once] Live dashboard (M6): cpu/mem/uptime per app, q to quit\n find [start] [--root <dir>] [--depth <n>] [--json] [--all]\n Find all configs under a root (default $HOME, depth 6) \u2014 solves PM2 pain: no need to remember dirs\n find \u2192 list with status (running/stopped/error)\n find start \u2192 start every stopped config (or --start flag)\n save Save current state to disk (snapshot)\n resurrect Start all apps from the saved state (M5)\n import-pm2 [dump.pm2] Import PM2 dump file (default ~/.pm2/dump.pm2) (M6)\n from-caddy [Caddyfile] [-o relife2.config.cjs] [--dry-run]\n Generate relife2 config from Caddyfile reverse_proxy upstreams (M6)\n dev <script> [--watch <paths>] [--hot|--no-hot] [--interpreter <bin>] [-- --args...]\n Watch+restart for local dev \u2014 bun --hot for .ts, manual fs.watch otherwise\n daemon-upgrade Upgrade daemon in place: save \u2192 shutdown old \u2192 spawn new \u2192 resurrect (no second daemon, ADR-0005)\n startup Install systemd user unit for autostart on boot (M5, Linux)\n kill Stop the daemon (apps are stopped gracefully)\n version Print version and runtime info\n help Show this help\n\nGlobal flags:\n -h, --help Show help\n -v, --version Print version\n\nDesign: exactly one locked daemon; commands that silently respawn the daemon\n(pm2 update style) do not exist by design. See TODO.md \u00A70 (anti-pitfalls).\n`;\n\nexport function printHelp(): void {\n console.log(HELP_TEXT);\n}\n", "import * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { ensureDaemonClient } from \"../daemon/client\";\n\ninterface Pm2Proc {\n name?: string;\n pm_exec_path?: string;\n pm_cwd?: string;\n pm_args?: string | string[];\n pm_env?: Record<string, string>;\n pm_out_log_path?: string;\n pm_err_log_path?: string;\n pm2_env?: Record<string, unknown>;\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n const target = args[0];\n const dumpPath =\n target !== undefined ? path.resolve(target) : path.join(os.homedir(), \".pm2\", \"dump.pm2\");\n\n if (!fs.existsSync(dumpPath)) {\n console.error(`import-pm2: dump file not found: ${dumpPath}`);\n console.error(\n \" pm2 saves to ~/.pm2/dump.pm2 via `pm2 save` \u2014 run that first, or pass a path:\",\n );\n console.error(\" relife2 import-pm2 /path/to/dump.pm2\");\n return 1;\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(dumpPath, \"utf8\"));\n } catch (err) {\n console.error(`import-pm2: cannot parse ${dumpPath}: ${(err as Error).message}`);\n return 1;\n }\n\n const list: Pm2Proc[] = Array.isArray(raw) ? raw : [];\n if (list.length === 0) {\n console.error(`import-pm2: dump file is empty: ${dumpPath}`);\n return 1;\n }\n\n // Convert PM2 dump entries to relife2 NormalizedApp-shaped inputs, then send to daemon\n const client = await ensureDaemonClient();\n try {\n let imported = 0;\n for (const entry of list) {\n const pm2env = (entry.pm2_env ?? {}) as Record<string, unknown>;\n const name = (pm2env.name as string | undefined) ?? entry.name ?? \"app\";\n const script = (pm2env.pm_exec_path as string | undefined) ?? entry.pm_exec_path;\n if (typeof script !== \"string\" || script === \"\") continue;\n const cwd = (pm2env.pm_cwd as string | undefined) ?? entry.pm_cwd ?? process.cwd();\n const argsRaw = pm2env.args ?? entry.pm_args;\n const args = Array.isArray(argsRaw)\n ? (argsRaw as string[])\n : typeof argsRaw === \"string\" && argsRaw !== \"\"\n ? (argsRaw as string).split(\" \")\n : [];\n const env =\n (pm2env.env as Record<string, string> | undefined) ??\n (entry.pm_env as Record<string, string> | undefined) ??\n {};\n const outFile = (pm2env.pm_out_log_path as string | undefined) ?? entry.pm_out_log_path;\n const errFile = (pm2env.pm_err_log_path as string | undefined) ?? entry.pm_err_log_path;\n const interpreterRaw =\n (pm2env.exec_interpreter as string | undefined) ??\n (pm2env.interpreter as string | undefined);\n const interpreter =\n typeof interpreterRaw === \"string\" && interpreterRaw !== \"\" && interpreterRaw !== \"none\"\n ? interpreterRaw\n : undefined;\n\n // Build a temporary config file for import via start\n const tmpConfig: { apps: Array<Record<string, unknown>> } = {\n apps: [\n {\n name,\n script,\n args,\n cwd,\n env,\n out_file: outFile,\n error_file: errFile,\n ...(interpreter !== undefined ? { interpreter } : {}),\n autorestart: pm2env.autorestart !== false,\n instances: pm2env.instances ?? 1,\n exec_mode: pm2env.exec_mode ?? \"fork\",\n },\n ],\n };\n\n // Write temp config and use daemon's start path via direct call\n const tmpPath = path.join(\n os.tmpdir(),\n `relife2-import-${Date.now()}-${Math.random().toString(36).slice(2)}.cjs`,\n );\n fs.writeFileSync(tmpPath, `module.exports = ${JSON.stringify(tmpConfig)}`, \"utf8\");\n try {\n const res = await client.call<{\n apps: Array<{ name: string; status: string; message?: string }>;\n }>(\"start\", {\n target: { type: \"config\", path: tmpPath },\n });\n for (const a of res.apps) {\n if (a.status === \"errored\") console.error(`x ${a.name}: ${a.message ?? \"failed\"}`);\n else {\n console.log(`ok import ${a.name}: ${a.status}`);\n imported++;\n }\n }\n } catch (err) {\n console.error(`import ${name}: ${(err as Error).message}`);\n } finally {\n try {\n fs.unlinkSync(tmpPath);\n } catch {}\n }\n }\n console.log(`\\nimported ${imported} app(s) from ${dumpPath}`);\n console.log(\n \"Note: review `relife2 list` and `relife2 describe <name>` \u2014 PM2 fields like cron/watch are imported if present.\",\n );\n return 0;\n } finally {\n client.close();\n }\n}\n", "import path from \"node:path\";\nimport { type LoadedConfig, loadConfigFile } from \"../config/loader\";\nimport { parseCliArgs } from \"../util/args\";\n\n/**\n * Hidden CLI helper: loads a config and prints the normalized apps + warnings.\n * Used by the golden tests and handy for debugging config resolution.\n */\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const file = positionals[0];\n if (file === undefined) {\n console.error(\"usage: relife2 inspect-config <config-file>\");\n return 1;\n }\n let loaded: LoadedConfig;\n try {\n loaded = await loadConfigFile(path.resolve(file));\n } catch (err) {\n console.error(`relife2: ${(err as Error).message}`);\n return 1;\n }\n console.log(JSON.stringify({ apps: loaded.apps, warnings: loaded.warnings }, null, 2));\n return 0;\n}\n", "import { runtimeDir } from \"../daemon/base\";\nimport { RpcClient, tryConnect } from \"../daemon/client\";\n\nexport async function run(_args: readonly string[]): Promise<number> {\n const sock = await tryConnect(runtimeDir());\n if (sock === null) {\n console.log(\"daemon is not running\");\n return 0;\n }\n const client = new RpcClient(sock);\n try {\n await client.call(\"shutdown\");\n console.log(\"daemon stopped\");\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\ninterface Summary {\n name: string;\n status: string;\n pid?: number;\n startTime?: number;\n restarts: number;\n crashStreak: number;\n exitCode?: number | null;\n exitSignal?: string | null;\n error?: string;\n}\n\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Summary[] }>(\"list\");\n if (res.apps.length === 0) {\n console.log(\"no apps (use `relife2 start <config|script>`)\");\n return 0;\n }\n const rows = res.apps.map((a) => ({\n name: a.name,\n status: a.status,\n pid: a.pid !== undefined ? String(a.pid) : \"-\",\n uptime: a.startTime !== undefined ? formatUptime(Date.now() - a.startTime) : \"-\",\n restarts: String(a.restarts),\n detail: a.error ?? \"\",\n }));\n printTable(rows);\n return 0;\n } finally {\n client.close();\n }\n}\n\nfunction formatUptime(ms: number): string {\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m${s % 60}s`;\n const h = Math.floor(m / 60);\n return `${h}h${m % 60}m`;\n}\n\nfunction printTable(rows: Array<Record<string, string>>): void {\n const first = rows[0];\n if (first === undefined) return;\n const cols = Object.keys(first);\n const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => (r[c] ?? \"\").length)));\n console.log(cols.map((c, i) => c.padEnd(widths[i] ?? 0)).join(\" \"));\n for (const row of rows) {\n console.log(cols.map((c, i) => (row[c] ?? \"\").padEnd(widths[i] ?? 0)).join(\" \"));\n }\n}\n", "import * as fs from \"node:fs\";\nimport { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\nimport { sleep } from \"../util/time\";\n\nconst VALUE_OPTS = new Set([\"lines\"]);\n\ninterface LogsResponse {\n name: string;\n files: string[];\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals, opts } = parseCliArgs(args, VALUE_OPTS);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 logs <name> [--lines N] [-f]\");\n return 1;\n }\n const lines = parseLines(opts.get(\"lines\") ?? opts.get(\"n\"));\n const follow = opts.has(\"f\") || opts.has(\"follow\");\n\n const client = await ensureDaemonClient();\n try {\n const info = await client.call<LogsResponse>(\"logs\", { name });\n if (info.files.length === 0) {\n console.log(`no log files configured for ${name}`);\n return 0;\n }\n let printed = 0;\n for (const file of info.files) {\n printed += printTail(file, lines);\n }\n if (printed === 0) {\n console.log(`(no log output yet for ${name})`);\n }\n if (follow) {\n console.log(`(following ${name}; press Ctrl+C to stop)`);\n await followFiles(info.files);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n\nfunction parseLines(v: unknown): number {\n const n = typeof v === \"string\" ? Number.parseInt(v, 10) : Number.NaN;\n return Number.isFinite(n) && n > 0 ? n : 50;\n}\n\nfunction printTail(file: string, lines: number): number {\n try {\n const text = fs.readFileSync(file, \"utf8\");\n const all = text.split(/\\r?\\n/);\n // Drop the trailing empty piece caused by a trailing newline.\n if (all.length > 0 && all[all.length - 1] === \"\") all.pop();\n const slice = all.slice(Math.max(0, all.length - lines));\n for (const line of slice) {\n if (line !== \"\") console.log(line);\n }\n return slice.length;\n } catch {\n return 0; // file not created yet\n }\n}\n\n/** Cheap tail -f via polling; good enough for M2 and platform-agnostic. */\nasync function followFiles(files: string[]): Promise<void> {\n const positions = new Map<string, number>();\n for (const f of files) {\n positions.set(f, 0);\n }\n process.once(\"SIGINT\", () => process.exit(0));\n process.once(\"SIGTERM\", () => process.exit(0));\n for (;;) {\n await sleep(400);\n for (const f of files) {\n const size = fileSize(f);\n const from = positions.get(f) ?? 0;\n if (size > from) {\n try {\n const fd = fs.openSync(f, \"r\");\n try {\n const buf = Buffer.alloc(size - from);\n fs.readSync(fd, buf, 0, buf.length, from);\n process.stdout.write(buf);\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n // ignore\n }\n }\n positions.set(f, size);\n }\n }\n}\n\nfunction fileSize(file: string): number {\n try {\n return fs.statSync(file).size;\n } catch {\n return 0;\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\n/** Pretty-prints bytes. */\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n const units = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let v = n / 1024;\n let i = 0;\n while (v >= 1024 && i < units.length - 1) {\n v /= 1024;\n i++;\n }\n return `${v.toFixed(1)} ${units[i] ?? \"KB\"}`;\n}\n\n/** Pretty-prints a duration in ms. */\nfunction fmtDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${Math.floor(ms / 60_000)}m ${Math.floor((ms % 60_000) / 1000)}s`;\n return `${Math.floor(ms / 3_600_000)}h ${Math.floor((ms % 3_600_000) / 60_000)}m`;\n}\n\ninterface AppMetrics {\n name: string;\n pid?: number;\n status: string;\n uptimeMs?: number;\n restarts: number;\n memory?: number;\n}\n\ninterface MetricsReport {\n daemon: {\n pid: number;\n uptimeMs: number;\n protocolVersion: number;\n appCount: number;\n };\n apps: AppMetrics[];\n}\n\n/**\n * Prints self-metrics: daemon uptime/RSS and per-app summary.\n */\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const report = await client.call<MetricsReport>(\"metrics\", {});\n console.log(\n `daemon: pid=${report.daemon.pid} uptime=${fmtDuration(report.daemon.uptimeMs)} protocol=${report.daemon.protocolVersion} apps=${report.daemon.appCount}`,\n );\n for (const a of report.apps) {\n const memStr = a.memory !== undefined ? ` mem=${fmtBytes(a.memory)}` : \"\";\n const uptimeStr = a.uptimeMs !== undefined ? ` uptime=${fmtDuration(a.uptimeMs)}` : \"\";\n console.log(\n ` ${a.name}: pid=${a.pid ?? \"?\"} status=${a.status} restarts=${a.restarts}${uptimeStr}${memStr}`,\n );\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\ninterface Summary {\n name: string;\n status: string;\n pid?: number;\n startTime?: number;\n restarts: number;\n crashStreak: number;\n error?: string;\n}\n\ninterface Metrics {\n daemon: { pid: number; uptimeMs: number; protocolVersion: number; appCount: number };\n apps: Array<{\n name: string;\n pid?: number;\n status: string;\n uptimeMs?: number;\n restarts: number;\n memory?: number;\n }>;\n}\n\nfunction formatUptime(ms: number): string {\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m${s % 60}s`;\n const h = Math.floor(m / 60);\n return `${h}h${m % 60}m`;\n}\n\nfunction formatMem(bytes?: number): string {\n if (bytes === undefined) return \"-\";\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nfunction clearScreen(): void {\n // ANSI clear screen + home cursor\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n}\n\nfunction pad(s: string, n: number): string {\n return s.length >= n ? s.slice(0, n) : s + \" \".repeat(n - s.length);\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n const once = args.includes(\"--once\");\n const client = await ensureDaemonClient();\n let running = true;\n\n function onExit(): void {\n running = false;\n try {\n client.close();\n } catch {}\n process.stdout.write(\"\\x1b[?25h\"); // show cursor\n process.exit(0);\n }\n process.on(\"SIGINT\", onExit);\n process.on(\"SIGTERM\", onExit);\n\n // Hide cursor during live view\n if (!once) process.stdout.write(\"\\x1b[?25l\");\n\n async function render(): Promise<void> {\n try {\n const [listRes, metricsRes] = await Promise.all([\n client.call<{ apps: Summary[] }>(\"list\"),\n client.call<Metrics>(\"metrics\"),\n ]);\n const memMap = new Map(metricsRes.apps.map((a) => [a.name, a.memory]));\n const uptimeMap = new Map(metricsRes.apps.map((a) => [a.name, a.uptimeMs]));\n\n if (!once) clearScreen();\n console.log(\n `relife2 monit \u2014 ${new Date().toLocaleString()} (q to quit${once ? \", --once\" : \"\"})`,\n );\n console.log(\n `daemon pid=${metricsRes.daemon.pid} uptime=${formatUptime(metricsRes.daemon.uptimeMs)} apps=${metricsRes.daemon.appCount}`,\n );\n console.log(\"\");\n const header = `${pad(\"name\", 20)} ${pad(\"status\", 10)} ${pad(\"pid\", 8)} ${pad(\"uptime\", 10)} ${pad(\"restarts\", 9)} ${pad(\"memory\", 10)} ${\"error\"}`;\n console.log(header);\n console.log(\"-\".repeat(header.length));\n for (const app of listRes.apps) {\n const mem = formatMem(memMap.get(app.name));\n const up =\n app.startTime !== undefined\n ? formatUptime(Date.now() - app.startTime)\n : uptimeMap.get(app.name) !== undefined\n ? formatUptime(uptimeMap.get(app.name) as number)\n : \"-\";\n const line = `${pad(app.name, 20)} ${pad(app.status, 10)} ${pad(app.pid !== undefined ? String(app.pid) : \"-\", 8)} ${pad(up, 10)} ${pad(String(app.restarts), 9)} ${pad(mem, 10)} ${app.error ?? \"\"}`;\n // Color status\n let colored = line;\n if (app.status === \"online\") colored = `\\x1b[32m${line}\\x1b[0m`;\n else if (app.status === \"errored\") colored = `\\x1b[31m${line}\\x1b[0m`;\n else if (app.status === \"stopped\") colored = `\\x1b[90m${line}\\x1b[0m`;\n console.log(colored);\n }\n console.log(\"\");\n if (!once) console.log(\"Press q or Ctrl+C to exit.\");\n } catch (err) {\n if (!once) clearScreen();\n console.error(`monit error: ${(err as Error).message}`);\n }\n }\n\n if (once) {\n await render();\n client.close();\n return 0;\n }\n\n // Live loop\n await render();\n // Enable raw mode for q keypress\n if (process.stdin.isTTY) {\n try {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on(\"data\", (d: Buffer) => {\n const s = d.toString(\"utf8\");\n if (s === \"q\" || s === \"Q\" || s === \"\\x03\") onExit();\n });\n } catch {}\n }\n\n while (running) {\n await new Promise((r) => setTimeout(r, 1000));\n if (running) await render();\n }\n return 0;\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const info = await client.call<{\n version: string;\n protocol: number;\n pid: number;\n uptime: number;\n }>(\"ping\");\n console.log(\n `relife2 daemon: online (pid ${info.pid}, v${info.version}, protocol ${info.protocol}, uptime ${info.uptime}s)`,\n );\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 reload <name|all>\");\n return 1;\n }\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string; status: string; pid?: number }> }>(\n \"reload\",\n { name },\n );\n for (const a of res.apps) {\n console.log(`ok ${a.name}: ${a.status}${a.pid !== undefined ? ` (pid ${a.pid})` : \"\"}`);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 restart <name|all>\");\n return 1;\n }\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string; status: string; pid?: number }> }>(\n \"restart\",\n { name },\n );\n for (const a of res.apps) {\n console.log(`ok ${a.name}: ${a.status}${a.pid !== undefined ? ` (pid ${a.pid})` : \"\"}`);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\ninterface ResurrectAppResult {\n name: string;\n status: string;\n pid?: number;\n message?: string;\n}\n\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: ResurrectAppResult[] }>(\"resurrect\");\n let failed = false;\n for (const app of res.apps) {\n if (app.status === \"errored\") {\n console.error(`x ${app.name}: ${app.message ?? \"failed to start\"}`);\n failed = true;\n } else if (app.message === \"already running\") {\n console.log(` ${app.name}: already running`);\n } else {\n console.log(\n `ok ${app.name}: ${app.status}${app.pid !== undefined ? ` (pid ${app.pid})` : \"\"}`,\n );\n }\n }\n return failed ? 1 : 0;\n } finally {\n client.close();\n }\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nconst VALUE_OPTS = new Set([\"max-size\", \"retain\", \"app\"]);\n\ninterface RotateAppResponse {\n name: string;\n rotated: string[];\n skipped: string[];\n}\n\n/**\n * Rotates app log files.\n * - `--max-size <bytes>`: files larger than this get rotated (default 10 MB).\n * - `--retain <n>`: keep at most n rotated generations per file (default 7).\n * - `<name>`: rotate only one app; otherwise rotate all apps managed by the daemon.\n * Rotation: rename app.out.log.1.gz \u2192 .2.gz, ..., app.out.log \u2192 .1, then gzip-compress.\n */\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals, opts } = parseCliArgs(args, VALUE_OPTS);\n const maxSize = parseSize(opts.get(\"max-size\") ?? \"10485760\");\n const retain = parseCount(opts.get(\"retain\") ?? \"7\");\n const appName = opts.get(\"app\");\n\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<RotateAppResponse[]>(\"rotate\", {\n app: appName ?? positionals[0],\n maxSizeBytes: maxSize,\n retain,\n });\n\n if (res.length === 0) {\n console.log(\"no log files to rotate\");\n return 0;\n }\n\n let totalRotated = 0;\n for (const entry of res) {\n if (entry.rotated.length > 0) {\n console.log(`ok ${entry.name}: rotated ${entry.rotated.length} file(s)`);\n for (const f of entry.rotated) console.log(` ${f}`);\n totalRotated += entry.rotated.length;\n } else if (entry.skipped.length > 0) {\n console.log(\n `ok ${entry.name}: no files exceed the size threshold (${entry.skipped.length} file(s) skipped)`,\n );\n }\n }\n console.log(`---\\n${totalRotated} file(s) rotated, retain=${retain}`);\n return 0;\n } finally {\n client.close();\n }\n}\n\nfunction parseSize(v: unknown): number {\n if (typeof v !== \"string\") return 10_485_760;\n const m = /^(\\d+(?:\\.\\d+)?)\\s*([kmg]?)$/i.exec(v.trim());\n if (!m) return 10_485_760;\n const num = Number.parseFloat(m[1] ?? \"\");\n if (!Number.isFinite(num)) return 10_485_760;\n const mult =\n { k: 1024, m: 1024 ** 2, g: 1024 ** 3, K: 1024, M: 1024 ** 2, G: 1024 ** 3 }[m[2] ?? \"\"] ?? 1;\n return Math.round(num * mult);\n}\n\nfunction parseCount(v: unknown): number {\n if (typeof v !== \"string\") return 7;\n const n = Number.parseInt(v, 10);\n return Number.isFinite(n) && n > 0 ? n : 7;\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\n\nexport async function run(_args: readonly string[]): Promise<number> {\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ ok: boolean; savedAt: string }>(\"save\");\n console.log(`state saved (${res.savedAt})`);\n return 0;\n } finally {\n client.close();\n }\n}\n", "import path from \"node:path\";\nimport { findDefaultConfig, looksLikeConfigFile } from \"../config/loader\";\nimport { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nconst VALUE_OPTS = new Set([\n \"name\",\n \"env\",\n \"instances\",\n \"exec-mode\",\n \"exec_mode\",\n \"interpreter\",\n \"cwd\",\n \"max-memory-restart\",\n \"max_memory_restart\",\n \"kill-timeout\",\n \"restart-delay\",\n \"watch-delay\",\n]);\n\ninterface StartAppResult {\n name: string;\n status: string;\n pid?: number;\n message?: string;\n}\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals, opts, passthrough } = parseCliArgs(args, VALUE_OPTS);\n let target = positionals[0];\n\n // relife2 start without args \u2192 try default config discovery (relife2.config.* / ecosystem.config.*)\n if (target === undefined) {\n const found = findDefaultConfig(process.cwd());\n if (found === null) {\n console.error(\n \"usage: relife2 start <config|script> [--name <n>] [--env <env>] [--instances <n>] [-- --app-args...]\\n also: relife2 start (no args) will look for relife2.config.{ts,js,cjs,mjs,json} or ecosystem.config.* in cwd\",\n );\n return 1;\n }\n target = found;\n }\n\n const nameVal = opts.get(\"name\");\n const name = typeof nameVal === \"string\" && nameVal !== \"\" ? nameVal : undefined;\n\n // Collect CLI overrides for start\n const envName = (opts.get(\"env\") as string | undefined) ?? undefined;\n const cliOverrides: Record<string, unknown> = {};\n if (envName !== undefined && envName !== \"\") cliOverrides._envName = envName;\n if (opts.has(\"instances\")) cliOverrides.instances = opts.get(\"instances\");\n if (opts.has(\"exec-mode\") || opts.has(\"exec_mode\"))\n cliOverrides.exec_mode = opts.get(\"exec-mode\") ?? opts.get(\"exec_mode\");\n if (opts.has(\"interpreter\")) cliOverrides.interpreter = opts.get(\"interpreter\");\n if (opts.has(\"cwd\")) cliOverrides.cwd = opts.get(\"cwd\");\n if (opts.has(\"max-memory-restart\") || opts.has(\"max_memory_restart\"))\n cliOverrides.max_memory_restart =\n opts.get(\"max-memory-restart\") ?? opts.get(\"max_memory_restart\");\n if (opts.has(\"kill-timeout\")) cliOverrides.kill_timeout = opts.get(\"kill-timeout\");\n if (opts.has(\"restart-delay\")) cliOverrides.restart_delay = opts.get(\"restart-delay\");\n if (opts.has(\"watch-delay\")) cliOverrides.watch_delay = opts.get(\"watch-delay\");\n\n const isConfig = looksLikeConfigFile(target);\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: StartAppResult[]; warnings?: string[] }>(\"start\", {\n target: {\n type: isConfig ? \"config\" : \"script\",\n path: path.resolve(target),\n name,\n args: passthrough.length > 0 ? passthrough : undefined,\n envName: envName ?? undefined,\n cliOverrides: Object.keys(cliOverrides).length > 0 ? cliOverrides : undefined,\n },\n });\n for (const w of res.warnings ?? []) console.error(`warning: ${w}`);\n let failed = false;\n for (const app of res.apps) {\n if (app.status === \"errored\") {\n console.error(`x ${app.name}: ${app.message ?? \"failed to start\"}`);\n failed = true;\n } else {\n console.log(\n `ok ${app.name}: ${app.status}${app.pid !== undefined ? ` (pid ${app.pid})` : \"\"}${\n app.message ? ` \u2014 ${app.message}` : \"\"\n }`,\n );\n }\n }\n return failed ? 1 : 0;\n } finally {\n client.close();\n }\n}\n", "import { execSync, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst SYSTEMD_USER_DIR = path.join(os.homedir(), \".config\", \"systemd\", \"user\");\nconst UNIT_NAME = \"relife2.service\";\n\nfunction getRelife2Bin(): string {\n // 1) If already installed as `relife2` on PATH, use that (covers npm global + single-binary in /usr/local/bin)\n const which = spawnSync(process.platform === \"win32\" ? \"where\" : \"which\", [\"relife2\"], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n const firstLine = which.stdout.trim().split(\"\\n\")[0]?.trim();\n if (which.status === 0 && firstLine !== undefined && firstLine !== \"\") {\n // On some systems `which` returns a shell shim (e.g. /usr/bin/relife2 -> node). That's still runnable directly.\n return firstLine;\n }\n\n // 2) Single-binary build: the current executable IS the relife2 binary (bun --compile)\n // In that case process.execPath is the binary, and argv[1] is not a .js file.\n const arg1 = process.argv[1];\n const isSingleBinary =\n arg1 === undefined ||\n (!arg1.endsWith(\".js\") && !arg1.endsWith(\".mjs\") && !arg1.endsWith(\".cjs\"));\n if (isSingleBinary) {\n // `process.execPath` itself is the relife2 binary\n return process.execPath;\n }\n\n // 3) Running as `node dist/cli.js` (dev / npm without global link): resolve relative to this file\n try {\n const thisFile = fileURLToPath(import.meta.url);\n // src/commands/startup.ts -> dist/commands/startup.js -> dist/cli.js\n const cliPath = path.resolve(path.dirname(thisFile), \"..\", \"cli.js\");\n if (fs.existsSync(cliPath)) {\n return `node ${cliPath}`;\n }\n } catch {\n // ignore\n }\n\n // 4) Fallback: node + whatever was invoked\n return `node ${path.resolve(arg1 ?? process.cwd())}`;\n}\n\nfunction generateUnit(bin: string): string {\n // Use Restart=always (more resilient than on-failure) \u2014 if daemon exits for any reason, systemd brings it back.\n // KillMode=process so systemd doesn't kill child apps when restarting the unit; daemon handles its own children.\n const envHint =\n process.env.RELIFE2_DIR !== undefined\n ? `\\nEnvironment=RELIFE2_DIR=${process.env.RELIFE2_DIR}`\n : \"\";\n return `[Unit]\nDescription=relife2 process manager daemon\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${bin}\nRestart=always\nRestartSec=2\nKillMode=process\nEnvironment=RELIFE2_DAEMON=1${envHint}\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nexport async function run(_args: readonly string[]): Promise<number> {\n if (process.platform === \"win32\") {\n console.error(\n \"relife2 startup: systemd is not available on Windows (use Task Scheduler instead)\",\n );\n return 1;\n }\n if (process.platform === \"darwin\") {\n console.error(\"relife2 startup: systemd is not available on macOS (use launchd instead)\");\n return 1;\n }\n\n const bin = getRelife2Bin();\n const unitContent = generateUnit(bin);\n const unitPath = path.join(SYSTEMD_USER_DIR, UNIT_NAME);\n\n // Ensure systemd user directory exists\n try {\n fs.mkdirSync(SYSTEMD_USER_DIR, { recursive: true });\n } catch (err) {\n console.error(`cannot create ${SYSTEMD_USER_DIR}: ${(err as Error).message}`);\n return 1;\n }\n\n // Write unit file\n try {\n fs.writeFileSync(unitPath, unitContent);\n console.log(`written systemd user unit: ${unitPath}`);\n } catch (err) {\n console.error(`cannot write ${unitPath}: ${(err as Error).message}`);\n return 1;\n }\n\n // Enable linger so the user's systemd runs without login (required on Oracle Linux 9 / Debian)\n try {\n const user = process.env.USER ?? os.userInfo().username ?? \"root\";\n execSync(`loginctl enable-linger ${user}`, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n console.log(`enabled linger for user ${user}`);\n } catch (err) {\n console.error(\n `warning: could not run 'loginctl enable-linger' (is systemd-logind running?): ${err instanceof Error ? err.message : String(err)}`,\n );\n console.error(\"your apps will only start after you log in. Run manually:\");\n console.error(` loginctl enable-linger ${process.env.USER ?? os.userInfo().username}`);\n }\n\n // Reload systemd and enable the unit\n try {\n execSync(\"systemctl --user daemon-reload\", { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n execSync(`systemctl --user enable ${UNIT_NAME}`, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n console.log(`enabled and reloaded: systemctl --user enable ${UNIT_NAME}`);\n } catch (err) {\n console.error(\n `warning: could not enable unit (is systemd available?): ${err instanceof Error ? err.message : String(err)}`,\n );\n console.error(\"run manually:\");\n console.error(\" systemctl --user daemon-reload\");\n console.error(` systemctl --user enable ${UNIT_NAME}`);\n }\n\n console.log(\"\");\n console.log(\"relife2 will now start automatically on boot.\");\n console.log(`ExecStart is: ${bin}`);\n console.log(\"To start now, run: systemctl --user start relife2.service\");\n console.log(\"To check status: systemctl --user status relife2.service\");\n return 0;\n}\n", "import { ensureDaemonClient } from \"../daemon/client\";\nimport { parseCliArgs } from \"../util/args\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n const { positionals } = parseCliArgs(args);\n const name = positionals[0];\n if (name === undefined) {\n console.error(\"usage: relife2 stop <name|all>\");\n return 1;\n }\n const client = await ensureDaemonClient();\n try {\n const res = await client.call<{ apps: Array<{ name: string; status: string; pid?: number }> }>(\n \"stop\",\n { name },\n );\n for (const a of res.apps) {\n console.log(`ok ${a.name}: ${a.status}${a.pid !== undefined ? ` (pid ${a.pid})` : \"\"}`);\n }\n return 0;\n } finally {\n client.close();\n }\n}\n", "import { dataDir, runtimeDir } from \"../daemon/base\";\nimport { RpcClient, spawnDaemon, tryConnect } from \"../daemon/client\";\nimport { PROTOCOL_VERSION } from \"../ipc/protocol\";\nimport { sleep } from \"../util/time\";\n\nexport async function run(args: readonly string[]): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n printUsage();\n return 0;\n }\n\n const runtime = runtimeDir();\n const data = dataDir();\n\n // Snapshot current daemon if any (tryConnect without protocol check \u2014 we want graceful upgrade even if stale)\n let sock = await tryConnect(runtime);\n if (sock === null) {\n console.log(\"daemon is not running \u2014 starting fresh\");\n spawnDaemon();\n for (let i = 0; i < 100; i++) {\n await sleep(100);\n sock = await tryConnect(runtime);\n if (sock !== null) break;\n }\n if (sock === null) {\n console.error(`cannot start daemon (runtime: ${runtime}); inspect logs/daemon.log`);\n return 1;\n }\n const client = new RpcClient(sock);\n try {\n const ping = await client.call<{ version: string; protocol: number; pid: number }>(\"ping\");\n if (ping.protocol !== PROTOCOL_VERSION) {\n console.error(\n `daemon protocol mismatch after start (daemon: ${ping.protocol}, cli: ${PROTOCOL_VERSION})`,\n );\n return 1;\n }\n console.log(`daemon started (pid ${ping.pid}, v${ping.version}, protocol ${ping.protocol})`);\n return 0;\n } finally {\n client.close();\n }\n }\n\n // Daemon is running \u2014 perform upgrade: save \u2192 shutdown \u2192 spawn new \u2192 resurrect\n const client = new RpcClient(sock);\n let oldPid: number | undefined;\n let oldVersion: string | undefined;\n let appsCount = 0;\n try {\n try {\n const ping = await client.call<{ version: string; protocol: number; pid: number }>(\"ping\");\n oldPid = ping.pid;\n oldVersion = ping.version;\n // protocol check is informational for upgrade \u2014 we still upgrade stale daemon\n if (ping.protocol !== PROTOCOL_VERSION) {\n console.error(\n `warning: daemon protocol ${ping.protocol} != cli ${PROTOCOL_VERSION} \u2014 forcing upgrade`,\n );\n }\n } catch {\n // ignore ping failure\n }\n try {\n const list = await client.call<{ apps: Array<{ name: string }> }>(\"list\");\n appsCount = list.apps.length;\n } catch {\n // ignore\n }\n // Ensure snapshot is persisted with current online state (autosave already did, but be explicit)\n try {\n await client.call(\"save\");\n } catch {\n // save is best-effort \u2014 journal may have it\n }\n\n console.log(\n `upgrading daemon${oldPid ? ` pid ${oldPid}` : \"\"}${oldVersion ? ` v${oldVersion}` : \"\"} (${appsCount} app(s)) \u2026`,\n );\n // Graceful shutdown \u2014 daemon will stop apps and clear lock/socket\n try {\n await client.call(\"shutdown\");\n } catch (err) {\n // shutdown closes socket after response; if it errors we still proceed to wait\n const msg = err instanceof Error ? err.message : String(err);\n if (!msg.includes(\"connection to daemon closed\") && !msg.includes(\"timeout\")) {\n console.error(`warning: shutdown call failed: ${msg}`);\n }\n }\n } finally {\n client.close();\n }\n\n // Wait for old daemon to release the socket/lock\n for (let i = 0; i < 50; i++) {\n await sleep(100);\n const probe = await tryConnect(runtime);\n if (probe === null) break;\n probe.destroy();\n // still alive\n if (i === 49) {\n console.error(\"old daemon did not exit within 5s \u2014 try `relife2 kill` and retry\");\n return 1;\n }\n }\n\n // Extra grace for lock file unlink\n await sleep(200);\n\n // Spawn new daemon\n console.log(`starting new daemon \u2026`);\n spawnDaemon();\n let newSock: import(\"node:net\").Socket | null = null;\n for (let i = 0; i < 100; i++) {\n await sleep(100);\n newSock = await tryConnect(runtime);\n if (newSock !== null) break;\n }\n if (newSock === null) {\n console.error(`new daemon did not appear within 10s (runtime: ${runtime}, data: ${data})`);\n return 1;\n }\n\n const newClient = new RpcClient(newSock);\n try {\n const ping = await newClient.call<{ version: string; protocol: number; pid: number }>(\"ping\");\n if (ping.protocol !== PROTOCOL_VERSION) {\n console.error(\n `new daemon protocol mismatch (daemon: ${ping.protocol}, cli: ${PROTOCOL_VERSION})`,\n );\n return 1;\n }\n console.log(`new daemon ready (pid ${ping.pid}, v${ping.version}, protocol ${ping.protocol})`);\n\n // Snapshot after shutdown is \"stopped\" \u2014 resurrect to bring apps back (autoResurrect on fresh start sees stopped)\n if (appsCount > 0) {\n try {\n const res = await newClient.call<{ apps: Array<{ name: string; status: string }> }>(\n \"resurrect\",\n );\n const started = res.apps.filter(\n (a) => a.status === \"online\" || a.status === \"starting\",\n ).length;\n console.log(`resurrected ${started}/${res.apps.length} app(s)`);\n } catch (err) {\n console.error(\n `warning: resurrect failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Verify\n try {\n const list = await newClient.call<{ apps: Array<{ name: string; status: string }> }>(\"list\");\n const online = list.apps.filter(\n (a) => a.status === \"online\" || a.status === \"starting\",\n ).length;\n console.log(\n `daemon-upgrade: ${oldPid ?? \"?\"} \u2192 ${ping.pid} (${online}/${list.apps.length} online)`,\n );\n } catch {\n console.log(`daemon-upgrade: ${oldPid ?? \"?\"} \u2192 ${ping.pid}`);\n }\n return 0;\n } finally {\n newClient.close();\n }\n}\n\nfunction printUsage(): void {\n console.log(`relife2 daemon-upgrade \u2014 upgrade daemon without losing app list\n\nUsage: relife2 daemon-upgrade\n\nFlow: save snapshot \u2192 graceful shutdown of old daemon (under lock) \u2192 spawn new\ndaemon \u2192 wait for ping (protocol check) \u2192 resurrect apps from snapshot.\n\nIf no daemon is running, just starts one. Never spawns a second daemon while\nthe old one is alive \u2014 relies on socket bind + lock file for singleton (ADR-0005).\nUse when you updated the relife2 binary or need to cycle the daemon cleanly.\n`);\n}\n", "import { VERSION } from \"../version\";\n\nexport function printVersion(): void {\n console.log(`relife2 ${VERSION}`);\n const [runtime, runtimeVersion] = detectRuntime();\n console.log(`runtime: ${runtime} ${runtimeVersion} (${process.platform} ${process.arch})`);\n}\n\n/** Detects the runtime the CLI is currently executed with (node or bun). */\nfunction detectRuntime(): readonly [string, string] {\n const g = globalThis as typeof globalThis & { Bun?: { version: string } };\n if (g.Bun !== undefined) {\n return [\"bun\", g.Bun.version];\n }\n return [\"node\", process.version];\n}\n", "import * as fs from \"node:fs\";\nimport type net from \"node:net\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport * as zlib from \"node:zlib\";\nimport { loadConfigFile, normalizeSingleApp } from \"../config/loader\";\nimport type { AppRecord, AppStartResult, NormalizedApp } from \"../types\";\nimport { ensureDirSync, isAlive, pathExists } from \"../util/fsx\";\nimport { fixCwd } from \"../util/portable\";\nimport { VERSION } from \"../version\";\nimport { resolveLogPaths } from \"./applog\";\nimport { acquireLock, dataDir, type LockHandle, runtimeDir } from \"./base\";\nimport { createDaemonLogger, type DaemonLogger } from \"./logger\";\nimport { ProcessManager } from \"./pm\";\nimport { StateStore } from \"./state\";\nimport type { DaemonTransport } from \"./transport\";\nimport { createDaemonTransport } from \"./transport\";\n\ninterface StartTarget {\n type: \"config\" | \"script\";\n path: string;\n name?: string;\n args?: string[];\n cwd?: string;\n interpreter?: string;\n env?: Record<string, string>;\n envName?: string;\n cliOverrides?: Record<string, unknown>;\n}\n\ninterface DaemonCtx {\n store: StateStore;\n pm: ProcessManager;\n logger: DaemonLogger;\n transport: DaemonTransport;\n lock: LockHandle;\n base: string;\n}\n\nexport async function runDaemon(): Promise<void> {\n const data = dataDir();\n const runtime = runtimeDir();\n ensureDirSync(path.join(data, \"logs\"));\n const logger = createDaemonLogger(data);\n logger.log(\"daemon starting\", { pid: process.pid, version: VERSION, platform: process.platform });\n\n const lock = acquireLock(runtime);\n if (lock === null) {\n logger.log(\"another daemon is already running; exiting\");\n return;\n }\n\n const transport = await createDaemonTransport(runtime);\n if (transport === null) {\n logger.log(\"transport is taken by another daemon; exiting\");\n lock.release();\n return;\n }\n\n const store = new StateStore(data);\n store.load();\n\n // Reap any orphan processes that survived a previous daemon crash\n // (their pid was persisted in snapshot). No status change yet \u2014 we need\n // to know which apps were supposed to be running for auto-resurrect.\n for (const rec of store.apps.values()) {\n if (rec.pid !== undefined && isAlive(rec.pid)) {\n try {\n process.kill(-rec.pid, \"SIGKILL\");\n } catch {\n try {\n process.kill(rec.pid, \"SIGKILL\");\n } catch {\n // already gone\n }\n }\n logger.log(`reaped orphan ${rec.name} pid=${rec.pid}`);\n }\n rec.pid = undefined;\n rec.child = undefined;\n rec.startTime = undefined;\n }\n\n // Figure out which apps were running before (autosave was on, so snapshot\n // reflects last known desired state). Stopped/errored apps stay stopped.\n const autoResurrect = [...store.apps.values()].filter(\n (rec) => rec.status === \"online\" || rec.status === \"starting\" || rec.status === \"restarting\",\n );\n // Mark them temporarily as stopped \u2014 spawnApp will set to online/starting\n for (const rec of autoResurrect) {\n rec.status = \"stopped\";\n }\n store.saveSync();\n store.journal(\"daemon-start\", { pid: process.pid, version: VERSION });\n\n const pm = new ProcessManager(store, logger, data);\n const ctx: DaemonCtx = { store, pm, logger, transport, lock, base: data };\n transport.onConnection((socket) => handleConnection(socket, ctx));\n\n logger.log(\"daemon ready\", { address: transport.address(), pid: process.pid });\n\n // Autosave semantics: after reboot, immediately resurrect apps that were\n // online when the snapshot was saved. This makes `save` unnecessary for\n // the common case \u2014 the daemon is self-healing (TODO.md \u00A70).\n for (const rec of autoResurrect) {\n // Portable fix: stale cwd from old home (debian \u2192 opt) \u2014 heal before deciding to skip\n const cwdFix = fixCwd(rec.config.cwd, rec.config.sourceDir);\n if (cwdFix.fixed && cwdFix.reason) {\n logger.log(cwdFix.reason);\n rec.config.cwd = cwdFix.path;\n }\n // Skip apps whose cwd truly doesn't exist (deleted project)\n if (!pathExists(rec.config.cwd)) {\n logger.log(`autosave: skipping ${rec.name} \u2014 cwd ${rec.config.cwd} does not exist`);\n rec.status = \"errored\";\n rec.error = `cwd does not exist: ${rec.config.cwd}`;\n continue;\n }\n logger.log(`autosave: resurrecting ${rec.name}`);\n pm.spawnApp(rec);\n }\n if (autoResurrect.length > 0) store.saveSync();\n\n process.on(\"SIGTERM\", onSignal);\n process.on(\"SIGINT\", onSignal);\n process.on(\"uncaughtException\", (e) =>\n logger.log(\"uncaughtException\", { error: String(e?.stack ?? e) }),\n );\n process.on(\"unhandledRejection\", (r) => logger.log(\"unhandledRejection\", { error: String(r) }));\n\n function onSignal(): void {\n logger.log(\"daemon received stop signal; shutting down\");\n void shutdownDaemon(ctx);\n }\n}\n\nasync function shutdownDaemon(ctx: DaemonCtx): Promise<void> {\n const { store, pm, logger, transport, lock } = ctx;\n pm.stopAllMonitors();\n pm.stopAll(\"stop\");\n await pm.waitForAllStopped(3000);\n store.saveSync();\n store.journal(\"daemon-stop\", {});\n transport.close();\n lock.release();\n logger.log(\"daemon exited\");\n setTimeout(() => process.exit(0), 50);\n}\n\nfunction handleConnection(socket: net.Socket, ctx: DaemonCtx): void {\n socket.setEncoding(\"utf8\");\n let buffer = \"\";\n socket.on(\"data\", (d: string | Buffer) => {\n buffer += typeof d === \"string\" ? d : d.toString(\"utf8\");\n let idx = buffer.indexOf(\"\\n\");\n while (idx >= 0) {\n const line = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 1);\n if (line.trim() !== \"\") void onLine(socket, ctx, line);\n idx = buffer.indexOf(\"\\n\");\n }\n });\n socket.on(\"error\", () => {\n try {\n socket.destroy();\n } catch {\n // ignore\n }\n });\n}\n\nasync function onLine(socket: net.Socket, ctx: DaemonCtx, line: string): Promise<void> {\n let req: { id: number; method: string; params?: unknown };\n try {\n req = JSON.parse(line) as { id: number; method: string; params?: unknown };\n } catch {\n return;\n }\n if (typeof req.id !== \"number\" || typeof req.method !== \"string\") return;\n\n const handler = METHODS[req.method];\n if (handler === undefined) {\n send(socket, {\n id: req.id,\n ok: false,\n error: { code: \"NO_METHOD\", message: `unknown method '${req.method}'` },\n });\n return;\n }\n\n try {\n const result = await handler(req.params, ctx);\n send(socket, { id: req.id, ok: true, result });\n } catch (err) {\n const code =\n err instanceof Error && \"code\" in err ? String((err as { code: unknown }).code) : \"ERROR\";\n const message = err instanceof Error ? err.message : String(err);\n send(socket, { id: req.id, ok: false, error: { code, message } });\n }\n\n if (req.method === \"shutdown\") {\n setImmediate(() => void shutdownDaemon(ctx));\n }\n}\n\nfunction send(\n socket: net.Socket,\n obj: { id: number; ok: boolean; result?: unknown; error?: { code: string; message: string } },\n): void {\n try {\n socket.write(`${JSON.stringify(obj)}\\n`);\n } catch {\n // peer gone\n }\n}\nconst METHODS: Record<string, (params: unknown, ctx: DaemonCtx) => Promise<unknown> | unknown> = {\n ping: () => ({\n version: VERSION,\n protocol: 1,\n pid: process.pid,\n uptime: Math.round(process.uptime()),\n }),\n\n list: (_p, { store }: DaemonCtx) => ({\n apps: [...store.apps.values()].map(summarize),\n }),\n\n describe: (params, { store }: DaemonCtx) => {\n const { name } = params as { name: string };\n if (typeof name !== \"string\" || name === \"\") {\n throw new Error(\"describe: missing app name\");\n }\n const rec = store.requireApp(name);\n const { child: _child, sink: _sink, ...rest } = rec;\n return rest;\n },\n\n start: async (params, ctx: DaemonCtx) => {\n const target = (params as { target?: StartTarget }).target;\n if (target === undefined || typeof target.path !== \"string\") {\n throw new Error(\"start: missing target\");\n }\n return startApps(target, ctx);\n },\n\n stop: (params, { store, pm }: DaemonCtx) => operate(\"stop\", params, store, pm),\n restart: (params, { store, pm }: DaemonCtx) => operate(\"restart\", params, store, pm),\n reload: async (params, ctx: DaemonCtx) => {\n const { store, pm, logger } = ctx;\n const name = (params as { name?: string }).name;\n const expanded =\n name === undefined || name === \"all\" ? [...store.apps.values()] : expandTargets(store, name);\n const results: Array<{ name: string; status: string; pid?: number }> = [];\n for (const rec of expanded) {\n if (rec.status !== \"online\" && rec.status !== \"starting\") {\n pm.spawnApp(rec);\n results.push({ name: rec.name, status: rec.status, pid: rec.pid });\n continue;\n }\n logger.log(`reload: graceful restart of ${rec.name}`);\n const prevPid = rec.pid;\n pm.stop(rec, \"restart\");\n // wait for new pid (best-effort 5s)\n const start = Date.now();\n while (Date.now() - start < 5000) {\n await new Promise((r) => setTimeout(r, 100));\n const st: string = rec.status;\n if (rec.pid !== undefined && rec.pid !== prevPid && (st === \"online\" || st === \"starting\"))\n break;\n if (st === \"errored\" || st === \"stopped\") break;\n }\n store.saveSync();\n results.push({ name: rec.name, status: rec.status, pid: rec.pid });\n }\n store.saveSync();\n store.journal(\"app-reload\", { names: results.map((r) => r.name) });\n return { apps: results };\n },\n\n logs: (params, { store, base }: DaemonCtx) => {\n const name = (params as { name?: string }).name;\n if (typeof name !== \"string\" || name === \"\") {\n throw new Error(\"logs: missing app name\");\n }\n const rec = store.requireApp(name);\n const paths = resolveLogPaths(rec.config, base);\n const files = paths.err === null ? [paths.out] : [paths.out, paths.err];\n return { name, files };\n },\n\n flush: (params, { store, base, logger }: DaemonCtx) => {\n const name = (params as { name?: string }).name;\n const targets =\n name === undefined || name === \"all\" ? [...store.apps.values()] : [store.requireApp(name)];\n const apps = targets.map((rec) => {\n const paths = resolveLogPaths(rec.config, base);\n const files = paths.err === null ? [paths.out] : [paths.out, paths.err];\n for (const f of files) {\n try {\n ensureDirSync(path.dirname(f));\n fs.writeFileSync(f, \"\");\n } catch (err) {\n logger.log(`flush ${rec.name}: cannot truncate ${f}: ${(err as Error).message}`);\n }\n }\n store.journal(\"app-flush\", { name: rec.name, files });\n return { name: rec.name, files };\n });\n return { apps };\n },\n\n delete: (params, { store, pm }: DaemonCtx) => {\n const res = operate(\"stop\", params, store, pm);\n for (const a of res.apps) {\n store.apps.delete(a.name);\n store.journal(\"app-delete\", { name: a.name });\n }\n store.saveSync();\n return res;\n },\n\n rotate: (params, { store, base, logger }: DaemonCtx) => {\n const { app, maxSizeBytes, retain } = params as {\n app?: string;\n maxSizeBytes?: number;\n retain?: number;\n };\n const max = maxSizeBytes ?? 10_485_760;\n const n = retain ?? 7;\n const targets =\n app === undefined || app === \"all\" ? [...store.apps.values()] : [store.requireApp(app)];\n const results: Array<{ name: string; rotated: string[]; skipped: string[] }> = [];\n for (const rec of targets) {\n const paths = resolveLogPaths(rec.config, base);\n const files = paths.err === null ? [paths.out] : [paths.out, paths.err];\n const rotated: string[] = [];\n const skipped: string[] = [];\n for (const f of files) {\n if (!pathExists(f)) continue;\n try {\n const stat = fs.statSync(f);\n if (stat.size >= max) {\n rotateFile(f, n);\n rotated.push(f);\n } else {\n skipped.push(f);\n }\n } catch (err) {\n logger.log(`rotate ${rec.name}: cannot rotate ${f}: ${(err as Error).message}`);\n skipped.push(f);\n }\n }\n if (rotated.length > 0 || skipped.length > 0) {\n store.journal(\"app-rotate\", { name: rec.name, files: rotated, skipped });\n results.push({ name: rec.name, rotated, skipped });\n }\n }\n return results;\n },\n\n metrics: (_params, { store, pm }: DaemonCtx) => {\n return {\n daemon: {\n pid: process.pid,\n uptimeMs: Math.round(process.uptime() * 1000),\n protocolVersion: 1,\n appCount: store.apps.size,\n },\n apps: pm.appMetrics(),\n };\n },\n\n save: (_params, { store, logger }: DaemonCtx) => {\n store.saveSync();\n store.journal(\"daemon-save\", {});\n logger.log(\"daemon state saved\");\n return { ok: true, savedAt: new Date().toISOString() };\n },\n\n resurrect: async (_params, ctx: DaemonCtx) => {\n const { store, pm, logger } = ctx;\n const results: AppStartResult[] = [];\n for (const rec of store.apps.values()) {\n if (rec.status === \"online\" || rec.status === \"starting\" || rec.status === \"restarting\") {\n results.push({ name: rec.name, status: rec.status, message: \"already running\" });\n continue;\n }\n logger.log(`resurrect: starting ${rec.name}`);\n pm.spawnApp(rec);\n results.push({ name: rec.name, status: rec.status, pid: rec.pid, message: rec.error });\n }\n store.saveSync();\n store.journal(\"daemon-resurrect\", { apps: results.length });\n return { apps: results };\n },\n\n doctor: (_params, { store, base, transport }: DaemonCtx) => {\n const checks: Array<{\n name: string;\n ok: boolean;\n issues: Array<{ severity: \"ok\" | \"warn\" | \"error\"; code: string; message: string }>;\n }> = [];\n\n // 1. State file integrity\n const snapshotPath = path.join(base, \"state\", \"snapshot.json\");\n const stateIssues: Array<{ severity: \"ok\" | \"warn\" | \"error\"; code: string; message: string }> =\n [];\n if (pathExists(snapshotPath)) {\n try {\n const data = JSON.parse(fs.readFileSync(snapshotPath, \"utf8\")) as {\n schema?: number;\n apps?: Record<string, unknown>;\n };\n if (data.schema === 1 && typeof data.apps === \"object\") {\n stateIssues.push({\n severity: \"ok\",\n code: \"SNAPSHOT_OK\",\n message: `snapshot.json valid (schema 1, ${Object.keys(data.apps ?? {}).length} apps)`,\n });\n } else {\n stateIssues.push({\n severity: \"error\",\n code: \"SNAPSHOT_SCHEMA\",\n message: `unexpected snapshot schema: ${data.schema}`,\n });\n }\n } catch (err) {\n stateIssues.push({\n severity: \"error\",\n code: \"SNAPSHOT_PARSE\",\n message: `cannot parse snapshot.json: ${(err as Error).message}`,\n });\n }\n } else {\n stateIssues.push({\n severity: \"warn\",\n code: \"SNAPSHOT_MISSING\",\n message: \"snapshot.json does not exist yet \u2014 no apps loaded\",\n });\n }\n checks.push({\n name: \"State integrity\",\n ok: !stateIssues.some((i) => i.severity === \"error\"),\n issues: stateIssues,\n });\n\n // 2. Lock consistency\n const lockFile = path.join(runtimeDir(), \"daemon.lock\");\n const lockIssues: Array<{ severity: \"ok\" | \"warn\" | \"error\"; code: string; message: string }> =\n [];\n if (pathExists(lockFile)) {\n try {\n const lock = JSON.parse(fs.readFileSync(lockFile, \"utf8\")) as { pid?: number };\n if (typeof lock.pid === \"number\" && isAlive(lock.pid)) {\n lockIssues.push({\n severity: \"ok\",\n code: \"LOCK_HELD\",\n message: `lock held by alive daemon pid=${lock.pid}`,\n });\n } else {\n lockIssues.push({\n severity: \"error\",\n code: \"LOCK_STALE\",\n message: `stale lock file (pid=${lock.pid} not alive)`,\n });\n }\n } catch (err) {\n lockIssues.push({\n severity: \"error\",\n code: \"LOCK_PARSE\",\n message: `cannot parse daemon.lock: ${(err as Error).message}`,\n });\n }\n } else {\n lockIssues.push({\n severity: \"error\",\n code: \"LOCK_MISSING\",\n message: \"daemon.lock missing \u2014 daemon may be unhealthy\",\n });\n }\n checks.push({\n name: \"Lock consistency\",\n ok: !lockIssues.some((i) => i.severity === \"error\"),\n issues: lockIssues,\n });\n\n // 3. Orphan / stale-pid detection\n const orphanIssues: Array<{\n severity: \"ok\" | \"warn\" | \"error\";\n code: string;\n message: string;\n }> = [];\n const orphans: string[] = [];\n for (const rec of store.apps.values()) {\n if (rec.pid !== undefined && rec.status === \"online\" && !isAlive(rec.pid)) {\n orphans.push(`${rec.name}(pid=${rec.pid})`);\n }\n }\n if (orphans.length === 0) {\n orphanIssues.push({\n severity: \"ok\",\n code: \"NO_ORPHANS\",\n message: \"all online apps have live pids\",\n });\n } else {\n orphanIssues.push({\n severity: \"error\",\n code: \"ORPHAN_APPS\",\n message: `online apps with dead pids: ${orphans.join(\", \")}`,\n });\n }\n checks.push({\n name: \"Orphan processes\",\n ok: !orphanIssues.some((i) => i.severity === \"error\"),\n issues: orphanIssues,\n });\n\n // 4. Transport health\n const transportIssues: Array<{\n severity: \"ok\" | \"warn\" | \"error\";\n code: string;\n message: string;\n }> = [];\n const addr = transport.address();\n if (addr) {\n transportIssues.push({\n severity: \"ok\",\n code: \"TRANSPORT_OK\",\n message: `listening on ${addr}`,\n });\n } else {\n transportIssues.push({\n severity: \"error\",\n code: \"TRANSPORT_DOWN\",\n message: \"transport is not accepting connections\",\n });\n }\n checks.push({\n name: \"Transport health\",\n ok: !transportIssues.some((i) => i.severity === \"error\"),\n issues: transportIssues,\n });\n\n // 5. Daemon uptime (informational)\n const uptimeIssues: Array<{\n severity: \"ok\" | \"warn\" | \"error\";\n code: string;\n message: string;\n }> = [\n {\n severity: \"ok\",\n code: \"UPTIME_OK\",\n message: `daemon running uptime=${Math.round(process.uptime())}s pid=${process.pid}`,\n },\n ];\n checks.push({ name: \"Daemon uptime\", ok: true, issues: uptimeIssues });\n\n return { checks, summary: summarizeChecks(checks) };\n },\n\n shutdown: () => ({ ok: true, message: \"shutting down\" }),\n};\n\nasync function startApps(\n target: StartTarget,\n ctx: DaemonCtx,\n): Promise<{ apps: AppStartResult[]; warnings: string[] }> {\n const { store, pm } = ctx;\n let apps: NormalizedApp[];\n let warnings: string[];\n if (target.type === \"config\") {\n const loaded = await loadConfigFile(target.path, { envName: target.envName });\n apps = loaded.apps;\n warnings = loaded.warnings;\n // Apply CLI overrides to each app (e.g. --instances --exec-mode)\n if (target.cliOverrides) {\n for (const app of apps) applyCliOverrides(app, target.cliOverrides);\n }\n } else {\n const input: Record<string, unknown> = {\n script: target.path,\n args: target.args,\n env: target.env,\n };\n if (target.name !== undefined) input.name = target.name;\n if (target.interpreter !== undefined) input.interpreter = target.interpreter;\n if (target.cwd !== undefined) input.cwd = target.cwd;\n if (target.cliOverrides) Object.assign(input, target.cliOverrides);\n const single = normalizeSingleApp(input, path.dirname(target.path), target.envName);\n apps = [single.app];\n warnings = single.warnings;\n }\n\n // Expand instances>1 into separate records (app:0, app:1, ...)\n const expanded: NormalizedApp[] = [];\n for (const app of apps) {\n if (app.instances <= 1) expanded.push(app);\n else {\n for (let i = 0; i < app.instances; i++) {\n const clone = {\n ...app,\n name: `${app.name}:${i}`,\n env: { ...app.env, NODE_APP_INSTANCE: String(i) },\n };\n expanded.push(clone);\n }\n }\n }\n\n const results: AppStartResult[] = [];\n for (const app of expanded) {\n const existing = store.apps.get(app.name);\n if (\n existing !== undefined &&\n (existing.status === \"online\" ||\n existing.status === \"restarting\" ||\n existing.status === \"starting\")\n ) {\n results.push({\n name: app.name,\n status: existing.status,\n pid: existing.pid,\n message: \"already running\",\n });\n continue;\n }\n let record: AppRecord;\n if (existing === undefined) {\n record = { name: app.name, config: app, status: \"stopped\", restarts: 0, crashStreak: 0 };\n store.apps.set(app.name, record);\n } else {\n record = existing;\n record.config = app;\n }\n pm.spawnApp(record);\n store.saveSync();\n results.push({ name: app.name, status: record.status, pid: record.pid, message: record.error });\n }\n return { apps: results, warnings };\n}\n\nfunction operate(\n kind: \"stop\" | \"restart\",\n params: unknown,\n store: StateStore,\n pm: ProcessManager,\n): { apps: Array<{ name: string; status: string; pid?: number }> } {\n const name = (params as { name?: string }).name;\n const targets =\n name === undefined || name === \"all\" ? [...store.apps.values()] : expandTargets(store, name);\n const result = targets.map((rec) => {\n pm.stop(rec, kind);\n store.saveSync();\n return { name: rec.name, status: rec.status, pid: rec.pid };\n });\n return { apps: result };\n}\n\nfunction expandTargets(store: StateStore, name: string): import(\"../types\").AppRecord[] {\n if (store.apps.has(name)) return [store.requireApp(name)];\n // Handle base name grouping for instances: \"app\" matches \"app:0\", \"app:1\", ...\n const matched = [...store.apps.values()].filter(\n (r) => r.name === name || r.name.startsWith(`${name}:`),\n );\n if (matched.length > 0) return matched;\n // Fallback: let requireApp throw proper error\n return [store.requireApp(name)];\n}\n\nfunction applyCliOverrides(\n app: import(\"../types\").NormalizedApp,\n overrides: Record<string, unknown>,\n): void {\n if (overrides.instances !== undefined) {\n const v = overrides.instances;\n if (v === \"max\" || v === \"MAX\") app.instances = os.cpus().length || 1;\n else {\n const n = Number(v);\n if (Number.isFinite(n) && n >= 1) app.instances = Math.round(n);\n }\n }\n if (overrides.exec_mode !== undefined) {\n const m = String(overrides.exec_mode).toLowerCase();\n if (m === \"cluster\" || m === \"cluster_mode\") app.execMode = \"cluster\";\n else if (m === \"fork\" || m === \"fork_mode\") app.execMode = \"fork\";\n }\n if (overrides.interpreter !== undefined) app.interpreter = String(overrides.interpreter);\n if (overrides.cwd !== undefined) app.cwd = String(overrides.cwd);\n if (overrides.max_memory_restart !== undefined) {\n try {\n // dynamic to avoid circular; memory parser is pure\n const mm = String(overrides.max_memory_restart);\n const num = Number(mm);\n if (Number.isFinite(num)) app.maxMemoryRestart = num;\n else {\n // parse like \"500M\"\n const units: Record<string, number> = {\n b: 1,\n kb: 1024,\n k: 1024,\n mb: 1024 * 1024,\n m: 1024 * 1024,\n gb: 1024 * 1024 * 1024,\n g: 1024 * 1024 * 1024,\n };\n const m = mm.toLowerCase().match(/^([0-9.]+)s*([a-z]*)$/);\n if (m) app.maxMemoryRestart = Math.round(Number(m[1]) * (units[m[2] as string] ?? 1));\n }\n } catch {}\n }\n if (overrides.kill_timeout !== undefined)\n app.killTimeout = Math.max(0, Number(overrides.kill_timeout) || 1600);\n if (overrides.restart_delay !== undefined)\n app.restartDelay = Math.max(0, Number(overrides.restart_delay) || 0);\n if (overrides.watch_delay !== undefined)\n app.watchDelay = Math.max(0, Number(overrides.watch_delay) || 1000);\n}\n\nfunction summarize(rec: AppRecord): Record<string, unknown> {\n return {\n name: rec.name,\n status: rec.status,\n pid: rec.pid,\n startTime: rec.startTime,\n restarts: rec.restarts,\n crashStreak: rec.crashStreak,\n exitCode: rec.exitCode,\n exitSignal: rec.exitSignal,\n error: rec.error,\n };\n}\n\n/**\n * Rotates a single log file: app.log \u2192 app.log.1 (gzip), shifting older indices up.\n */\nfunction rotateFile(file: string, retain: number): void {\n // Shift existing rotated files: .n.gz \u2192 .(n+1).gz\n for (let i = retain - 1; i >= 0; i--) {\n const oldName = i === 0 ? file : `${file}.${i}.gz`;\n const newName = `${file}.${i + 1}.gz`;\n if (pathExists(oldName)) {\n if (i + 1 >= retain) {\n // Exceeds retain \u2014 delete the oldest generation\n fs.unlinkSync(oldName);\n } else {\n // Shift: rename or compress+rename\n if (i === 0) {\n // Compress the current file into .1.gz\n const content = fs.readFileSync(file);\n fs.unlinkSync(file);\n const gz = zlib.gzipSync(content);\n fs.writeFileSync(newName, gz);\n } else {\n fs.renameSync(oldName, newName);\n }\n }\n }\n }\n}\n\n/** Counts checks by status for the doctor summary. */\nfunction summarizeChecks(\n checks: Array<{ ok: boolean; issues: Array<{ severity: \"ok\" | \"warn\" | \"error\" }> }>,\n): { total: number; ok: number; warnings: number; errors: number } {\n let ok = 0;\n let warnings = 0;\n for (const c of checks) {\n const hasError = c.issues.some((i) => i.severity === \"error\");\n const hasWarn = c.issues.some((i) => i.severity === \"warn\");\n if (hasError) {\n /* counted as error below */\n } else if (hasWarn) {\n warnings++;\n } else {\n ok++;\n }\n }\n const errors = checks.filter((c) => !c.ok).length;\n return { total: checks.length, ok, warnings, errors };\n}\n", "import * as fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { NormalizedApp } from \"../types\";\nimport { formatDate } from \"../util/datefmt\";\nimport { ensureDirSync } from \"../util/fsx\";\n\nconst DEFAULT_LOG_FORMAT = \"YYYY-MM-DD HH:mm:ss.SSS Z\";\nconst DEFAULT_LOGS_DIR = (base: string) => path.join(base, \"logs\");\n\nexport interface AppLogPaths {\n out: string;\n /** null when merge_logs is set (everything lands in `out`). */\n err: string | null;\n}\n\n/**\n * Resolves where an app's stdout/stderr actually go.\n * Relative paths in out_file/error_file are resolved against the app cwd;\n * without custom paths the default `logs/<name>.out.log` / `.err.log` are used.\n */\nexport function resolveLogPaths(app: NormalizedApp, base: string): AppLogPaths {\n const safe = app.name.replace(/[^\\w.-]/g, \"_\");\n const out = app.outFile\n ? path.resolve(app.cwd, app.outFile)\n : path.join(DEFAULT_LOGS_DIR(base), `${safe}.out.log`);\n\n if (app.mergeLogs) return { out, err: null };\n const err = app.errFile\n ? path.resolve(app.cwd, app.errFile)\n : path.join(DEFAULT_LOGS_DIR(base), `${safe}.err.log`);\n return { out, err };\n}\n\n/**\n * Per-app log sink: splits incoming chunks into lines, optionally prefixes a\n * timestamp, and appends to the resolved files. Never throws (logging must\n * not crash the daemon). Merge mode routes stderr into the same file as stdout.\n */\nexport class AppLogSink {\n private readonly prefix: string;\n private outSink = \"\";\n private errSink = \"\";\n\n constructor(\n app: NormalizedApp,\n private readonly paths: AppLogPaths,\n ) {\n const timestamped = app.time || app.logDateFormat !== undefined;\n this.prefix = timestamped ? `${formatDate(app.logDateFormat ?? DEFAULT_LOG_FORMAT)} ` : \"\";\n }\n\n out(chunk: string): void {\n this.writeLeftover(\n this.paths.out,\n chunk,\n () => this.outSink,\n (v) => (this.outSink = v),\n );\n }\n\n err(chunk: string): void {\n if (this.paths.err === null) {\n this.writeLeftover(\n this.paths.out,\n chunk,\n () => this.outSink,\n (v) => (this.outSink = v),\n );\n return;\n }\n this.writeLeftover(\n this.paths.err,\n chunk,\n () => this.errSink,\n (v) => (this.errSink = v),\n );\n }\n\n private writeLeftover(\n target: string,\n text: string,\n get: () => string,\n set: (v: string) => void,\n ): void {\n const joined = get() + text;\n const lines = joined.split(\"\\n\");\n set(lines.pop() ?? \"\");\n for (const line of lines) {\n const out = `${this.prefix}${line}\\n`;\n try {\n ensureDirSync(path.dirname(target));\n fs.appendFileSync(target, out);\n } catch {\n // never break the daemon over log writes\n }\n }\n }\n}\n", "/**\n * Tiny moment-style date formatter (no dependencies, ADR-0002).\n * Supports the tokens used by PM2 configs: YYYY MM DD HH mm ss SSS Z ZZ A a.\n * - Z -> local UTC offset as \u00B1HHMM (\"+0300\")\n * - ZZ -> local UTC offset as \u00B1HH:MM (\"+03:00\")\n * Unknown text passes through unchanged.\n */\nexport function formatDate(pattern: string, date: Date = new Date()): string {\n const y = date.getFullYear();\n const mo = date.getMonth() + 1;\n const d = date.getDate();\n const h = date.getHours();\n const mi = date.getMinutes();\n const s = date.getSeconds();\n const ms = date.getMilliseconds();\n\n const offset = date.getTimezoneOffset();\n const sign = offset <= 0 ? \"+\" : \"-\";\n const abs = Math.abs(offset);\n const oh = String(Math.floor(abs / 60)).padStart(2, \"0\");\n const om = String(abs % 60).padStart(2, \"0\");\n const z = `${sign}${oh}${om}`;\n const zz = `${sign}${oh}:${om}`;\n\n const ampm = h < 12 ? \"AM\" : \"PM\";\n const pad = (n: number, len = 2): string => String(n).padStart(len, \"0\");\n\n // Longest/specific tokens first so e.g. 'YY' can't eat into 'YYYY'.\n return pattern\n .replaceAll(\"YYYY\", String(y))\n .replaceAll(\"YY\", String(y).slice(-2))\n .replaceAll(\"MM\", pad(mo))\n .replaceAll(\"DD\", pad(d))\n .replaceAll(\"HH\", pad(h))\n .replaceAll(\"mm\", pad(mi))\n .replaceAll(\"ss\", pad(s))\n .replaceAll(\"SSS\", pad(ms, 3))\n .replaceAll(\"ZZ\", zz)\n .replaceAll(\"Z\", z)\n .replaceAll(\"A\", ampm)\n .replaceAll(\"a\", ampm.toLowerCase())\n .replaceAll(\"M\", String(mo))\n .replaceAll(\"D\", String(d))\n .replaceAll(\"H\", String(h));\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ensureDirSync } from \"../util/fsx\";\n\nexport interface DaemonLogger {\n log(msg: string, extra?: Record<string, unknown>): void;\n appOut(name: string, chunk: string): void;\n appErr(name: string, chunk: string): void;\n}\n\n/** File-backed logger. The daemon runs detached, so everything goes to files. */\nexport function createDaemonLogger(base: string): DaemonLogger {\n const logsDir = path.join(base, \"logs\");\n ensureDirSync(logsDir);\n const mainFile = path.join(logsDir, \"daemon.log\");\n const outRoot = logsDir;\n\n function log(msg: string, extra?: Record<string, unknown>): void {\n const line = `${JSON.stringify({ ts: new Date().toISOString(), msg, ...(extra ?? {}) })}\\n`;\n try {\n fs.appendFileSync(mainFile, line);\n } catch {\n // logging must never crash the daemon\n }\n }\n\n function safeName(name: string): string {\n return name.replace(/[^\\w.-]/g, \"_\");\n }\n\n function appOut(name: string, chunk: string): void {\n try {\n fs.appendFileSync(path.join(outRoot, `${safeName(name)}.out.log`), chunk);\n } catch {\n // ignore\n }\n }\n\n function appErr(name: string, chunk: string): void {\n try {\n fs.appendFileSync(path.join(outRoot, `${safeName(name)}.err.log`), chunk);\n } catch {\n // ignore\n }\n }\n\n return { log, appOut, appErr };\n}\n", "import { type ChildProcess, spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { AppRecord, NormalizedApp, StopReason } from \"../types\";\nimport { cronMatches } from \"../util/cron\";\nimport { fixCwd, fixScript } from \"../util/portable\";\nimport { AppLogSink, resolveLogPaths } from \"./applog\";\nimport { buildSpawnSpec, type SpawnSpec } from \"./command\";\nimport type { DaemonLogger } from \"./logger\";\nimport { processRss } from \"./memproc\";\nimport type { StateStore } from \"./state\";\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** How long to wait for an IPC 'ready' message before marking an app online. */\nconst READY_TIMEOUT_MS = 30_000;\n\n/** Memory check interval (ms). */\nconst MEMORY_CHECK_INTERVAL_MS = 5000;\n\n/** Cron check interval (ms) \u2014 every minute. */\nconst CRON_CHECK_INTERVAL_MS = 60_000;\n\n/** IPC 'ready' works with node children; bun children verified since bun 1.1+ (\u00A77.7 test). */\nfunction canUseIpc(app: NormalizedApp): boolean {\n const interp = app.interpreter;\n if (interp === \"none\") return false;\n if (interp === \"bun\" || interp === \"node\") return true;\n if (interp !== undefined) return false; // custom interpreter path \u2014 unverified\n return process.execPath.toLowerCase().includes(\"node\");\n}\n\n/**\n * Owns child processes: spawn, graceful (SIGTERM \u2192 kill_timeout \u2192 SIGKILL),\n * restart policy (min_uptime / crashStreak / max_restarts / autorestart),\n * and tree-kill by process group (detached=y on POSIX = leader of its own group).\n */\nexport class ProcessManager {\n private readonly timers = new Map<string, NodeJS.Timeout>();\n private readonly killTimers = new Map<string, NodeJS.Timeout>();\n private readonly readyTimers = new Map<string, NodeJS.Timeout>();\n private readonly watchTimers = new Map<string, NodeJS.Timeout>();\n private readonly watchers = new Map<string, fs.FSWatcher[]>();\n private memMonitor?: NodeJS.Timeout;\n private cronMonitor?: NodeJS.Timeout;\n private cronLastCheck = 0;\n\n constructor(\n private readonly store: StateStore,\n private readonly logger: DaemonLogger,\n private readonly base: string,\n ) {}\n\n spawnApp(record: AppRecord, opts?: { resetCrashStreak?: boolean }): void {\n this.clearTimer(record.name);\n this.clearKillTimer(record.name);\n this.clearReadyTimer(record.name);\n this.stopWatch(record.name); // drop any watchers from a prior spawn\n\n // \u2500\u2500 portable fix: stale absolute paths from old home (debian \u2192 opt, etc.) \u2500\u2500\n // Do this before buildSpawnSpec so the snapshot is healed and crash-loops don't DOS the host.\n const cwdFix = fixCwd(record.config.cwd, record.config.sourceDir);\n if (cwdFix.fixed && cwdFix.reason) {\n this.logger.log(cwdFix.reason);\n this.store.journal(\"app-portable-fix\", {\n name: record.name,\n field: \"cwd\",\n from: record.config.cwd,\n to: cwdFix.path,\n });\n record.config.cwd = cwdFix.path;\n }\n if (path.isAbsolute(record.config.script) && !fs.existsSync(record.config.script)) {\n const sFix = fixScript(record.config.script, record.config.cwd, record.config.sourceDir);\n if (sFix.fixed && sFix.reason) {\n this.logger.log(sFix.reason);\n this.store.journal(\"app-portable-fix\", {\n name: record.name,\n field: \"script\",\n from: record.config.script,\n to: sFix.path,\n });\n record.config.script = sFix.path;\n } else if (!sFix.fixed) {\n // No candidate \u2014 fail fast without retry storm (pm2 would hot-loop here)\n this.fail(\n record,\n `script not found: '${record.config.script}'. ${sFix.reason ?? \"\"} Run 'relife2 find --root ${path.dirname(record.config.sourceDir)}' to locate configs or fix the config.`,\n );\n this.store.saveSync();\n return;\n }\n }\n\n let spec: SpawnSpec;\n try {\n spec = buildSpawnSpec(record.config);\n } catch (err) {\n this.fail(record, `spawn config: ${errMsg(err)}`);\n return;\n }\n\n record.status = \"starting\";\n // Manual starts clear the crash streak; auto-restarts must keep it\n // so a crash-loop can still reach 'errored' (max_restarts).\n if (opts?.resetCrashStreak !== false) {\n record.crashStreak = 0;\n }\n this.touch(record);\n\n // A fresh sink each spawn: paths may differ between restarts.\n record.sink = new AppLogSink(record.config, resolveLogPaths(record.config, this.base));\n const sink = record.sink;\n\n let child: ChildProcess;\n const bin = spec.cmd[0];\n if (bin === undefined) {\n this.fail(record, \"spawn config: empty command\");\n return;\n }\n const useIpc = canUseIpc(record.config);\n try {\n child = spawn(bin, spec.cmd.slice(1), {\n cwd: spec.cwd,\n env: spec.env,\n stdio: useIpc ? [\"ignore\", \"pipe\", \"pipe\", \"ipc\"] : [\"ignore\", \"pipe\", \"pipe\"],\n detached: process.platform !== \"win32\",\n });\n } catch (err) {\n this.fail(record, `spawn failed: ${errMsg(err)}`);\n return;\n }\n\n record.child = child;\n record.pid = child.pid;\n record.startTime = Date.now();\n record.exitCode = undefined;\n record.exitSignal = undefined;\n record.error = undefined;\n record.stopRequested = undefined;\n record.exitAt = undefined;\n record.status = record.config.waitReady ? \"starting\" : \"online\";\n this.touch(record);\n this.store.journal(\"app-start\", { name: record.name, pid: child.pid, cmd: spec.cmd.join(\" \") });\n this.logger.log(\n `started ${record.name} (pid ${child.pid}) ${spec.cmd.join(\" \")}${spec.note ? ` [${spec.note}]` : \"\"}`,\n );\n\n child.stdout?.on(\"data\", (d: Buffer) => sink.out(d.toString(\"utf8\")));\n child.stderr?.on(\"data\", (d: Buffer) => sink.err(d.toString(\"utf8\")));\n\n if (useIpc && record.config.waitReady) {\n child.on(\"message\", (msg: unknown) => {\n if (record.child !== child) return;\n if (\n msg === \"ready\" ||\n (msg !== null && typeof msg === \"object\" && (msg as { type?: string }).type === \"ready\")\n ) {\n this.markReady(record);\n }\n });\n const timer = setTimeout(() => {\n this.readyTimers.delete(record.name);\n if (record.child === child && record.status === \"starting\") {\n this.logger.log(\n `app ${record.name} did not send 'ready' within ${READY_TIMEOUT_MS}ms; marking online`,\n );\n record.status = \"online\";\n this.touch(record);\n }\n }, READY_TIMEOUT_MS);\n this.readyTimers.set(record.name, timer);\n }\n\n child.on(\"error\", (err) => this.fail(record, `process error: ${errMsg(err)}`));\n child.on(\"exit\", (code, signal) => this.onExit(record, code, signal));\n\n // Start memory monitoring if this app has a limit\n this.maybeStartMemMonitor();\n // Start watch/cron if configured\n this.maybeStartWatch(record);\n this.maybeStartCronMonitor();\n }\n\n private maybeStartMemMonitor(): void {\n if (this.memMonitor !== undefined) return;\n const anyLimited = [...this.store.apps.values()].some(\n (rec) => rec.config.maxMemoryRestart !== undefined && rec.config.maxMemoryRestart > 0,\n );\n if (!anyLimited) return;\n this.memMonitor = setInterval(() => this.checkMemory(), MEMORY_CHECK_INTERVAL_MS);\n // Don't keep the event loop alive solely for this timer\n if (typeof this.memMonitor.unref === \"function\") this.memMonitor.unref();\n }\n\n private checkMemory(): void {\n for (const rec of this.store.apps.values()) {\n const limit = rec.config.maxMemoryRestart;\n if (limit === undefined || limit <= 0) continue;\n const pid = rec.pid;\n if (pid === undefined) continue;\n const rss = processRss(pid);\n if (rss === undefined) continue;\n if (rss > limit) {\n this.logger.log(\n `app ${rec.name} exceeded memory limit (${rss} > ${limit} bytes); restarting`,\n );\n this.store.journal(\"app-restart-memory\", {\n name: rec.name,\n pid,\n rss,\n limit,\n });\n // Graceful restart via stop(reason='restart')\n this.stop(rec, \"restart\");\n }\n }\n }\n\n /** Marks a wait_ready app as online once it signals readiness over IPC. */\n private markReady(record: AppRecord): void {\n const t = this.readyTimers.get(record.name);\n if (t !== undefined) {\n clearTimeout(t);\n this.readyTimers.delete(record.name);\n }\n if (record.status === \"starting\") {\n record.status = \"online\";\n this.store.journal(\"app-ready\", { name: record.name });\n this.logger.log(`app ${record.name} ready`);\n this.touch(record);\n }\n }\n\n /** Graceful stop. `reason === 'restart'` respawns after the process actually exits. */\n stop(record: AppRecord, reason: StopReason): void {\n this.clearTimer(record.name);\n this.clearKillTimer(record.name);\n this.clearReadyTimer(record.name);\n this.stopWatch(record.name);\n record.stopRequested = reason;\n\n if (record.pid === undefined) {\n // Nothing to signal: honor the requested end state directly.\n if (reason === \"restart\") {\n if (record.status === \"stopped\" || record.status === \"errored\") {\n record.stopRequested = undefined;\n this.spawnApp(record);\n }\n return;\n }\n this.setStateStopped(record);\n return;\n }\n\n record.status = \"stopping\";\n this.touch(record);\n this.store.journal(\"app-stop\", { name: record.name, reason });\n this.signalTree(record, \"SIGTERM\");\n\n const timeout = record.config.killTimeout;\n this.killTimers.set(\n record.name,\n setTimeout(() => {\n this.killTimers.delete(record.name);\n if (record.pid !== undefined) {\n this.logger.log(`kill_timeout reached for ${record.name}; sending SIGKILL`);\n this.signalTree(record, \"SIGKILL\");\n }\n }, timeout),\n );\n }\n\n stopAll(reason: StopReason): void {\n for (const record of this.store.apps.values()) {\n this.stop(record, reason);\n }\n }\n\n waitForAllStopped(timeoutMs: number): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n return new Promise((resolve) => {\n const tick = (): void => {\n const running = [...this.store.apps.values()].some((r) => r.pid !== undefined);\n if (!running || Date.now() >= deadline) {\n resolve();\n return;\n }\n setTimeout(tick, 100);\n };\n tick();\n });\n }\n\n private onExit(record: AppRecord, code: number | null, signal: string | null): void {\n if (!record.child) return; // already handled (spawn error)\n record.child = undefined;\n record.pid = undefined;\n record.exitCode = code;\n record.exitSignal = signal;\n record.exitAt = Date.now();\n this.clearKillTimer(record.name);\n\n const uptime = record.startTime !== undefined ? Math.max(0, Date.now() - record.startTime) : 0;\n this.store.journal(\"app-exit\", { name: record.name, code, signal, uptime });\n this.logger.log(`app ${record.name} exited (code=${code} signal=${signal} uptime=${uptime}ms)`);\n\n const reason = record.stopRequested;\n if (reason !== undefined) {\n record.stopRequested = undefined;\n if (reason === \"restart\") {\n this.spawnApp(record);\n } else {\n this.setStateStopped(record);\n }\n return;\n }\n\n // Unexpected exit -> restart policy (TODO.md M1).\n if (uptime >= record.config.minUptime) {\n record.crashStreak = 0; // stable run -> clean slate\n } else {\n record.crashStreak += 1;\n }\n this.touch(record);\n\n if (!record.config.autorestart) {\n this.setStateStopped(record);\n return;\n }\n if (record.crashStreak > record.config.maxRestarts) {\n record.status = \"errored\";\n record.error =\n `exited ${String(code)} after ${record.crashStreak} crashes inside min_uptime ` +\n `(${record.config.minUptime}ms); max_restarts=${record.config.maxRestarts}`;\n this.store.journal(\"app-errored\", { name: record.name, error: record.error });\n this.touch(record);\n this.logger.log(`app ${record.name} entered errored state: ${record.error}`);\n return;\n }\n\n record.restarts += 1;\n record.status = \"restarting\";\n this.store.journal(\"app-restart-scheduled\", { name: record.name, restarts: record.restarts });\n this.touch(record);\n this.timers.set(\n record.name,\n setTimeout(() => {\n this.timers.delete(record.name);\n if (record.status === \"restarting\") {\n this.spawnApp(record, { resetCrashStreak: false });\n }\n }, record.config.restartDelay),\n );\n }\n\n private fail(record: AppRecord, message: string): void {\n record.child = undefined;\n record.pid = undefined;\n record.status = \"errored\";\n record.error = message;\n this.store.journal(\"app-errored\", { name: record.name, error: message });\n this.touch(record);\n this.logger.log(`app ${record.name} errored: ${message}`);\n }\n\n private setStateStopped(record: AppRecord): void {\n record.status = \"stopped\";\n this.store.journal(\"app-stopped\", { name: record.name });\n this.touch(record);\n this.logger.log(`app ${record.name} stopped`);\n }\n\n private signalTree(record: AppRecord, signal: NodeJS.Signals | \"SIGKILL\"): void {\n const pid = record.pid;\n if (pid === undefined) return;\n if (process.platform === \"win32\") {\n // Best effort on Windows: kill the whole subtree hard.\n try {\n spawn(\"taskkill\", [\"/pid\", String(pid), \"/T\", \"/F\"]);\n } catch {\n // ignore\n }\n return;\n }\n try {\n process.kill(-pid, signal); // whole process group (detached=y)\n } catch {\n try {\n process.kill(pid, signal);\n } catch {\n // already gone\n }\n }\n }\n\n private clearTimer(name: string): void {\n const t = this.timers.get(name);\n if (t !== undefined) {\n clearTimeout(t);\n this.timers.delete(name);\n }\n }\n\n private clearKillTimer(name: string): void {\n const t = this.killTimers.get(name);\n if (t !== undefined) {\n clearTimeout(t);\n this.killTimers.delete(name);\n }\n }\n\n private clearReadyTimer(name: string): void {\n const t = this.readyTimers.get(name);\n if (t !== undefined) {\n clearTimeout(t);\n this.readyTimers.delete(name);\n }\n }\n\n /** Stops the background memory monitor (called during shutdown). */\n stopMemMonitor(): void {\n if (this.memMonitor !== undefined) {\n clearInterval(this.memMonitor);\n this.memMonitor = undefined;\n }\n }\n\n /** Stops all watch + cron monitors (called during shutdown). */\n stopAllMonitors(): void {\n this.stopMemMonitor();\n if (this.cronMonitor !== undefined) {\n clearInterval(this.cronMonitor);\n this.cronMonitor = undefined;\n }\n for (const watchers of this.watchers.values()) {\n for (const w of watchers) {\n try {\n w.close();\n } catch {\n // ignore\n }\n }\n }\n this.watchers.clear();\n for (const t of this.watchTimers.values()) clearTimeout(t);\n this.watchTimers.clear();\n }\n\n // \u2500\u2500\u2500 Watch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private maybeStartWatch(record: AppRecord): void {\n const watch = record.config.watch;\n if (watch === undefined || watch === false) return;\n if (this.watchers.has(record.name)) return; // already watching\n\n const rawPaths = Array.isArray(watch)\n ? watch.map((p) => path.resolve(record.config.cwd, p))\n : [record.config.cwd];\n\n const watchers: fs.FSWatcher[] = [];\n for (const target of rawPaths) {\n try {\n if (!fs.existsSync(target)) {\n this.logger.log(`watch: path '${target}' does not exist yet; skipping`);\n continue;\n }\n const stat = fs.statSync(target);\n // If target is a file, watch its parent directory and filter.\n // On Linux fs.watch({recursive:true}) is not supported \u2014 walk subdirs.\n if (!stat.isDirectory()) {\n const dir = path.dirname(target);\n const base = path.basename(target);\n const watcher = fs.watch(dir, (_eventType, filename) => {\n if (filename !== null && filename !== base) return;\n this.onWatchChange(record.name, target);\n });\n watchers.push(watcher);\n continue;\n }\n if (process.platform === \"win32\" || process.platform === \"darwin\") {\n const watcher = fs.watch(target, { recursive: true }, () => {\n this.onWatchChange(record.name, target);\n });\n watchers.push(watcher);\n } else {\n // Linux: recursive not supported \u2014 watch every sub-directory.\n const dirs = this.collectSubDirs(target);\n for (const dir of dirs) {\n try {\n const watcher = fs.watch(dir, () => {\n this.onWatchChange(record.name, target);\n });\n watchers.push(watcher);\n } catch (err) {\n this.logger.log(`watch: cannot watch '${dir}': ${errMsg(err)}`);\n }\n }\n }\n } catch (err) {\n this.logger.log(`watch: cannot watch '${target}': ${errMsg(err)}`);\n }\n }\n if (watchers.length > 0) {\n this.watchers.set(record.name, watchers);\n this.logger.log(`watch: started for ${record.name} (${watchers.length} path(s))`);\n }\n }\n\n /** Collects `root` and all its nested sub-directories (BFS, ignores errors/symlink loops). */\n private collectSubDirs(root: string): string[] {\n const out: string[] = [root];\n const seen = new Set<string>([root]);\n const queue: string[] = [root];\n while (queue.length > 0) {\n const dir = queue.shift() as string;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith(\".\")) continue; // skip .git, node_modules hidden is ok but keep scan cheap\n // Don't descend into node_modules/.git to avoid fd explosion\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const full = path.join(dir, entry.name);\n if (seen.has(full)) continue;\n seen.add(full);\n out.push(full);\n queue.push(full);\n }\n }\n return out;\n }\n\n private onWatchChange(name: string, dir: string): void {\n const existing = this.watchTimers.get(name);\n if (existing !== undefined) clearTimeout(existing);\n const rec = this.store.apps.get(name);\n if (rec === undefined) return;\n const delay = rec.config.watchDelay ?? 1000;\n this.watchTimers.set(\n name,\n setTimeout(() => {\n this.watchTimers.delete(name);\n if (rec.pid !== undefined && (rec.status === \"online\" || rec.status === \"starting\")) {\n this.logger.log(`watch: change detected in ${dir}; restarting ${name}`);\n this.store.journal(\"app-restart-watch\", { name, dir });\n this.stop(rec, \"restart\");\n }\n }, delay),\n );\n }\n\n /** Stops and removes all watchers for a single app (called on stop/spawn). */\n private stopWatch(name: string): void {\n const watchers = this.watchers.get(name);\n if (watchers !== undefined) {\n for (const w of watchers) {\n try {\n w.close();\n } catch {\n // ignore\n }\n }\n this.watchers.delete(name);\n }\n const t = this.watchTimers.get(name);\n if (t !== undefined) {\n clearTimeout(t);\n this.watchTimers.delete(name);\n }\n }\n\n // \u2500\u2500\u2500 Cron \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private maybeStartCronMonitor(): void {\n if (this.cronMonitor !== undefined) return;\n const anyCron = [...this.store.apps.values()].some(\n (rec) => rec.config.cronRestart !== undefined,\n );\n if (!anyCron) return;\n this.cronMonitor = setInterval(() => this.checkCron(), CRON_CHECK_INTERVAL_MS);\n if (typeof this.cronMonitor.unref === \"function\") this.cronMonitor.unref();\n // Check immediately on start\n this.checkCron();\n }\n\n private checkCron(): void {\n const now = Date.now();\n const currentMinute = Math.floor(now / 60_000);\n if (currentMinute === this.cronLastCheck) return; // already checked this minute\n this.cronLastCheck = currentMinute;\n\n for (const rec of this.store.apps.values()) {\n const expr = rec.config.cronRestart;\n if (expr === undefined) continue;\n try {\n if (cronMatches(expr, new Date(now))) {\n this.logger.log(`cron: '${expr}' matched for ${rec.name}; restarting`);\n this.store.journal(\"app-restart-cron\", { name: rec.name, expr });\n this.stop(rec, \"restart\");\n }\n } catch (err) {\n this.logger.log(`cron: error checking '${expr}' for ${rec.name}: ${errMsg(err)}`);\n }\n }\n }\n\n private touch(_record: AppRecord): void {\n this.store.saveSync();\n }\n\n /** Returns the daemon's own RSS in bytes (for self-metrics). */\n daemonMemory(): number {\n try {\n return process.memoryUsage().rss;\n } catch {\n return 0;\n }\n }\n\n /** Returns a sanitized snapshot of the managed apps for the metrics command. */\n appMetrics(): Array<{\n name: string;\n pid?: number;\n status: string;\n uptimeMs?: number;\n restarts: number;\n memory?: number;\n }> {\n return [...this.store.apps.values()].map((rec) => ({\n name: rec.name,\n pid: rec.pid,\n status: rec.status,\n uptimeMs: rec.startTime !== undefined ? Date.now() - rec.startTime : undefined,\n restarts: rec.restarts,\n memory: rec.pid !== undefined ? processRss(rec.pid) : undefined,\n }));\n }\n}\n", "import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport type { NormalizedApp } from \"../types\";\n\nexport interface SpawnSpec {\n cmd: string[];\n cwd: string;\n env: Record<string, string>;\n /** Human-readable note about how the interpreter was chosen (for logging). */\n note?: string;\n}\n\nconst JS_RE = /\\.(?:c?js|mjs|ts|mts|cts)$/i;\n\nexport function isJsScript(p: string): boolean {\n return JS_RE.test(p);\n}\n\n/**\n * Detects a bun project by checking for bun.lockb / bun.lock in the script's\n * directory (or any ancestor up to $HOME / filesystem root).\n */\nexport function isBunProject(scriptDir: string): boolean {\n let dir = scriptDir;\n const home = process.env.HOME ?? \"\";\n while (true) {\n if (existsSync(path.join(dir, \"bun.lockb\")) || existsSync(path.join(dir, \"bun.lock\"))) {\n return true;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // filesystem root\n if (home !== \"\" && dir === home) break; // don't scan above $HOME\n dir = parent;\n }\n return false;\n}\n\n/**\n * Builds the actual spawn line (TODO.md \u00A72 \"Spawn rules\"):\n * - interpreter: 'none' \u2192 run script directly (java, python, binaries\u2026);\n * - interpreter: 'bun'/\u2026 \u2192 run that interpreter with the script;\n * - JS/TS script + bun project (bun.lockb/bun.lock) \u2192 bun (auto-detected);\n * - JS/TS script \u2192 default to the current runtime (node; bun when daemon runs under bun);\n * - anything else \u2192 run the script directly.\n */\nexport function buildSpawnSpec(app: NormalizedApp): SpawnSpec {\n const script = app.script;\n let cmd: string[];\n let note: string | undefined;\n if (app.interpreter === \"none\") {\n cmd = [script, ...app.args];\n } else if (app.interpreter !== undefined) {\n cmd = [app.interpreter, script, ...app.args];\n } else if (isJsScript(script)) {\n if (isBunProject(app.cwd)) {\n cmd = [\"bun\", script, ...app.args];\n note = \"auto-detected bun project (bun.lockb/bun.lock); using bun\";\n } else {\n cmd = [process.execPath, script, ...app.args];\n }\n } else {\n cmd = [script, ...app.args];\n }\n if (!cmd[0]) throw new Error(\"empty command\");\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (v !== undefined) env[k] = v;\n }\n Object.assign(env, app.env);\n return { cmd, cwd: app.cwd, env, note };\n}\n", "import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\n\n/**\n * Returns the RSS (resident set size) of a process in bytes, or undefined if\n * the process is not alive or the reading fails.\n *\n * - Linux: reads /proc/<pid>/status (VmRSS).\n * - macOS: `ps -o rss= -p <pid>` (rss is in KB).\n * - Windows: `wmic process where ProcessId=<pid> get WorkingSetSize` (bytes).\n */\nexport function processRss(pid: number): number | undefined {\n if (pid <= 0) return undefined;\n try {\n if (process.platform === \"linux\") {\n return rssFromProc(pid);\n }\n if (process.platform === \"darwin\") {\n return rssFromPs(pid);\n }\n return rssFromWmic(pid);\n } catch {\n return undefined;\n }\n}\n\nfunction rssFromProc(pid: number): number | undefined {\n const status = fs.readFileSync(`/proc/${pid}/status`, \"utf8\");\n const match = /^VmRSS:\\s+(\\d+)\\s+kB/m.exec(status);\n if (match?.[1] === undefined) return undefined;\n return Number(match[1]) * 1024;\n}\n\nfunction rssFromPs(pid: number): number | undefined {\n const out = execFileSync(\"ps\", [\"-o\", \"rss=\", \"-p\", String(pid)], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n if (out === \"\") return undefined;\n const kb = Number(out);\n if (!Number.isFinite(kb) || kb < 0) return undefined;\n return Math.round(kb * 1024);\n}\n\nfunction rssFromWmic(pid: number): number | undefined {\n const out = execFileSync(\n \"wmic\",\n [\"process\", \"where\", `ProcessId=${pid}`, \"get\", \"WorkingSetSize\"],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n },\n );\n const lines = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l !== \"\" && l !== \"WorkingSetSize\");\n if (lines.length === 0) return undefined;\n const bytes = Number(lines[0]);\n if (!Number.isFinite(bytes) || bytes < 0) return undefined;\n return Math.round(bytes);\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { RpcError } from \"../ipc/protocol\";\nimport type { AppRecord } from \"../types\";\nimport { atomicWriteFileSync, ensureDirSync, readJsonFile } from \"../util/fsx\";\n\n/**\n * Persistence for app state.\n * - snapshot.json \u2014 source of truth, written atomically (tmp + rename + fsync);\n * - journal.jsonl \u2014 append-only audit trail of lifecycle events.\n */\nexport class StateStore {\n readonly apps = new Map<string, AppRecord>();\n private readonly snapshotPath: string;\n private readonly journalPath: string;\n\n constructor(base: string) {\n const stateDir = path.join(base, \"state\");\n ensureDirSync(stateDir);\n this.snapshotPath = path.join(stateDir, \"snapshot.json\");\n this.journalPath = path.join(stateDir, \"journal.jsonl\");\n }\n\n load(): void {\n const data = readJsonFile<{ apps?: Record<string, AppRecord> }>(this.snapshotPath);\n if (!data?.apps) return;\n for (const [name, rec] of Object.entries(data.apps)) {\n if (rec === null || typeof rec !== \"object\" || rec.config === undefined) continue;\n this.apps.set(name, {\n name: rec.name ?? name,\n config: rec.config,\n status: (rec.status as AppRecord[\"status\"]) ?? \"stopped\",\n pid: typeof rec.pid === \"number\" ? rec.pid : undefined,\n startTime: undefined,\n exitAt: rec.exitAt,\n exitCode: rec.exitCode,\n exitSignal: rec.exitSignal,\n restarts: rec.restarts ?? 0,\n crashStreak: rec.crashStreak ?? 0,\n error: rec.error,\n });\n }\n }\n\n saveSync(): void {\n const appsObj: Record<string, unknown> = {};\n for (const [name, rec] of this.apps) {\n const { child: _child, sink: _sink, ...rest } = rec;\n appsObj[name] = rest;\n }\n atomicWriteFileSync(\n this.snapshotPath,\n JSON.stringify({ schema: 1, savedAt: new Date().toISOString(), apps: appsObj }, null, 2),\n );\n }\n\n journal(type: string, data?: Record<string, unknown>): void {\n const line = `${JSON.stringify({ ts: new Date().toISOString(), type, ...(data ?? {}) })}\\n`;\n try {\n fs.appendFileSync(this.journalPath, line);\n } catch {\n // journaling is best-effort\n }\n }\n\n requireApp(name: string): AppRecord {\n const rec = this.apps.get(name);\n if (!rec) throw new RpcError(\"NOT_FOUND\", `app '${name}' is not in this daemon's list`);\n return rec;\n }\n}\n", "import fs from \"node:fs\";\nimport net from \"node:net\";\nimport { defaultPort, portFilePath, unixSockPath } from \"./base\";\n\nexport interface DaemonTransport {\n address(): string;\n close(): void;\n onConnection(cb: (socket: net.Socket) => void): void;\n}\n\n/**\n * Exclusive transport: the socket bind itself *is* the singleton guarantee on\n * POSIX (a second daemon cannot bind the same unix socket). On Windows the TCP\n * bind is belt-and-suspendered with the lock file; a stale socket gets reaped.\n */\nexport async function createDaemonTransport(base: string): Promise<DaemonTransport | null> {\n return process.platform === \"win32\" ? createWinTransport(base) : createPosixTransport(base);\n}\n\nasync function createPosixTransport(base: string): Promise<DaemonTransport | null> {\n const sockPath = unixSockPath(base);\n for (let attempt = 0; attempt < 2; attempt++) {\n const server = net.createServer();\n const err = await listenOnce(server, sockPath);\n if (err === null) return serverTransport(server, sockPath);\n if ((err as NodeJS.ErrnoException).code !== \"EADDRINUSE\") return null;\n // Socket exists: alive daemon, or stale leftover from a crash.\n if (await probeActive(sockPath)) return null;\n try {\n fs.unlinkSync(sockPath);\n } catch {\n // raced with another starter; re-try listens below\n }\n }\n return null;\n}\n\nasync function createWinTransport(base: string): Promise<DaemonTransport | null> {\n const preferred = readPortFile(base) ?? defaultPort(base);\n for (let port = preferred; port < preferred + 20; port++) {\n const server = net.createServer();\n const err = await listenOnce(server, { host: \"127.0.0.1\", port });\n if (err === null) {\n writePortFile(base, port);\n return serverTransport(server, `127.0.0.1:${port}`);\n }\n if ((err as NodeJS.ErrnoException).code !== \"EADDRINUSE\") return null;\n }\n return null;\n}\n\nfunction serverTransport(server: net.Server, address: string): DaemonTransport {\n return {\n address: () => address,\n close: () => server.close(),\n onConnection: (cb) => server.on(\"connection\", cb),\n };\n}\n\nfunction listenOnce(\n server: net.Server,\n addr: string | { host: string; port: number },\n): Promise<NodeJS.ErrnoException | null> {\n return new Promise((resolve) => {\n server.once(\"error\", (err: NodeJS.ErrnoException) => resolve(err));\n server.once(\"listening\", () => resolve(null));\n server.listen(addr);\n });\n}\n\nfunction probeActive(sockPath: string): Promise<boolean> {\n return new Promise((resolve) => {\n const sock = net.connect(sockPath);\n const timer = setTimeout(() => {\n sock.destroy();\n resolve(false);\n }, 400);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n sock.destroy();\n resolve(true);\n });\n sock.once(\"error\", () => {\n clearTimeout(timer);\n resolve(false);\n });\n });\n}\n\nfunction readPortFile(base: string): number | null {\n try {\n const raw = fs.readFileSync(portFilePath(base), \"utf8\");\n return Number.parseInt(raw.trim(), 10) || null;\n } catch {\n return null;\n }\n}\n\nfunction writePortFile(base: string, port: number): void {\n try {\n fs.writeFileSync(portFilePath(base), String(port));\n } catch {\n // non-fatal\n }\n}\n", "import { run as runDelete } from \"./commands/delete\";\nimport { run as runDescribe } from \"./commands/describe\";\nimport { run as runDev } from \"./commands/dev\";\nimport { run as runDoctor } from \"./commands/doctor\";\nimport { run as runFind } from \"./commands/find\";\nimport { run as runFlush } from \"./commands/flush\";\nimport { run as runFromCaddy } from \"./commands/fromCaddy\";\nimport { printHelp } from \"./commands/help\";\nimport { run as runImportPm2 } from \"./commands/importpm2\";\nimport { run as runInspectConfig } from \"./commands/inspectconfig\";\nimport { run as runKill } from \"./commands/kill\";\nimport { run as runList } from \"./commands/list\";\nimport { run as runLogs } from \"./commands/logs\";\nimport { run as runMetrics } from \"./commands/metrics\";\nimport { run as runMonit } from \"./commands/monit\";\nimport { run as runPing } from \"./commands/ping\";\nimport { run as runReload } from \"./commands/reload\";\nimport { run as runRestart } from \"./commands/restart\";\nimport { run as runResurrect } from \"./commands/resurrect\";\nimport { run as runRotate } from \"./commands/rotate\";\nimport { run as runSave } from \"./commands/save\";\nimport { run as runStart } from \"./commands/start\";\nimport { run as runStartup } from \"./commands/startup\";\nimport { run as runStop } from \"./commands/stop\";\nimport { run as runUpgrade } from \"./commands/upgrade\";\nimport { printVersion } from \"./commands/version\";\nimport { runDaemon } from \"./daemon/daemon\";\n\n/** Implemented commands, keyed by name. Receives args after the command. */\nconst COMMANDS: Record<string, (args: readonly string[]) => Promise<number>> = {\n start: runStart,\n stop: runStop,\n restart: runRestart,\n reload: runReload,\n delete: runDelete,\n list: runList,\n ls: runList,\n status: runList,\n describe: runDescribe,\n ping: runPing,\n kill: runKill,\n logs: runLogs,\n flush: runFlush,\n rotate: runRotate,\n doctor: runDoctor,\n metrics: runMetrics,\n monit: runMonit,\n find: runFind,\n \"from-caddy\": runFromCaddy,\n save: runSave,\n resurrect: runResurrect,\n startup: runStartup,\n \"import-pm2\": runImportPm2,\n \"inspect-config\": runInspectConfig,\n dev: runDev,\n \"daemon-upgrade\": runUpgrade,\n upgrade: runUpgrade,\n version: async () => {\n printVersion();\n return 0;\n },\n help: async () => {\n printHelp();\n return 0;\n },\n};\n\n/** Commands from TODO.md \u00A73 that are not implemented yet, keyed to their milestone. */\nconst PLANNED: Record<string, string> = {};\n\n/** CLI entry point. Returns the process exit code. */\nexport async function run(argv: readonly string[]): Promise<number> {\n // Daemon mode \u2014 this process *is* the daemon (spawned with RELIFE2_DAEMON=1).\n if (process.env.RELIFE2_DAEMON === \"1\") {\n await runDaemon();\n return 0;\n }\n\n const args = argv.slice(2);\n const command = args[0];\n\n // Global --version/--help without a command\n if (command === undefined) {\n if (hasFlag(args, \"v\", \"version\") || hasFlag(args, \"h\", \"help\")) {\n if (hasFlag(args, \"v\", \"version\")) printVersion();\n else printHelp();\n return 0;\n }\n printHelp();\n return 0;\n }\n\n // If first arg is a known command, let it handle its own --help/--version\n if (COMMANDS[command] !== undefined) {\n // Still allow top-level `relife2 --version` with no command; otherwise delegate\n if ((command === \"--help\" || command === \"-h\") && args.length === 1) {\n printHelp();\n return 0;\n }\n if ((command === \"--version\" || command === \"-v\") && args.length === 1) {\n printVersion();\n return 0;\n }\n const impl = COMMANDS[command]!;\n return impl(args.slice(1));\n }\n\n // Not a known command \u2014 maybe a global flag mistaken as command?\n if (hasFlag(args, \"v\", \"version\")) {\n printVersion();\n return 0;\n }\n if (hasFlag(args, \"h\", \"help\")) {\n printHelp();\n return 0;\n }\n\n const milestone = PLANNED[command];\n if (milestone !== undefined) {\n console.error(\n `relife2: command '${command}' is not implemented yet (planned in ${milestone}, see TODO.md)`,\n );\n return 1;\n }\n\n console.error(`relife2: unknown command '${command}'`);\n console.error(\"run 'relife2 --help' to see available commands\");\n return 1;\n}\n\nfunction hasFlag(args: readonly string[], short: string, long: string): boolean {\n return args.includes(`-${short}`) || args.includes(`--${long}`);\n}\n\nprocess.exitCode = await run(process.argv);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fs", "path", "require", "path", "fs", "path", "path", "fs", "path", "child", "run", "spawn", "fs", "path", "path", "run", "spawn", "run", "fs", "os", "path", "fs", "os", "path", "fs", "os", "path", "path", "pathToFileURL", "os", "path", "run", "os", "client", "run", "fs", "os", "path", "open", "close", "run", "printUsage", "hasBun", "fs", "os", "path", "run", "path", "os", "args", "path", "run", "path", "run", "run", "fs", "VALUE_OPTS", "run", "run", "formatUptime", "run", "run", "run", "run", "run", "VALUE_OPTS", "run", "run", "path", "VALUE_OPTS", "run", "path", "spawnSync", "fs", "os", "path", "run", "run", "run", "printUsage", "client", "fs", "os", "path", "fs", "path", "pad", "path", "fs", "path", "path", "fs", "spawn", "fs", "path", "existsSync", "path", "process", "isBunProject", "fs", "path", "spawn", "watch", "fs", "path", "path", "fs", "fs", "net", "net", "fs", "path", "os", "run"]
|
|
7
|
+
}
|