pidnap 0.0.0-dev.0 → 0.0.0-dev.1
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/dist/cli.mjs +67 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +12 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{logger-crc5neL8.mjs → logger-uliALovz.mjs} +103 -10
- package/dist/logger-uliALovz.mjs.map +1 -0
- package/dist/task-list-CIdbB3wM.d.mts.map +1 -1
- package/package.json +1 -1
- package/src/api/server.ts +2 -2
- package/src/index.ts +1 -0
- package/src/lazy-process.ts +25 -10
- package/src/manager.ts +40 -3
- package/src/port-utils.ts +76 -0
- package/src/tree-kill.ts +138 -0
- package/dist/logger-crc5neL8.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as ProcessDefinitionSchema, a as TaskStateSchema, c as CronProcessStateSchema, h as RestartingProcessStateSchema, i as TaskList, m as RestartingProcessOptionsSchema, n as EnvManager, o as CronProcess, p as RestartingProcess, s as CronProcessOptionsSchema, t as logger } from "./logger-
|
|
2
|
+
import { _ as ProcessDefinitionSchema, a as TaskStateSchema, c as CronProcessStateSchema, h as RestartingProcessStateSchema, i as TaskList, m as RestartingProcessOptionsSchema, n as EnvManager, o as CronProcess, p as RestartingProcess, s as CronProcessOptionsSchema, t as logger, y as treeKill } from "./logger-uliALovz.mjs";
|
|
3
3
|
import { createClient } from "./client.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { createServer } from "node:http";
|
|
@@ -9,8 +9,10 @@ import { RPCHandler } from "@orpc/server/node";
|
|
|
9
9
|
import { implement, onError } from "@orpc/server";
|
|
10
10
|
import * as v from "valibot";
|
|
11
11
|
import { oc } from "@orpc/contract";
|
|
12
|
+
import { exec } from "node:child_process";
|
|
12
13
|
import { cwd } from "node:process";
|
|
13
14
|
import { mkdirSync } from "node:fs";
|
|
15
|
+
import { promisify } from "node:util";
|
|
14
16
|
import { tsImport } from "tsx/esm/api";
|
|
15
17
|
import Table from "cli-table3";
|
|
16
18
|
|
|
@@ -129,10 +131,10 @@ const listProcesses = os.processes.list.handler(async ({ context }) => {
|
|
|
129
131
|
return Array.from(context.manager.getRestartingProcesses().values()).map(serializeProcess);
|
|
130
132
|
});
|
|
131
133
|
const addProcess = os.processes.add.handler(async ({ input, context }) => {
|
|
132
|
-
return serializeProcess(context.manager.addProcess(input.name, input.definition));
|
|
134
|
+
return serializeProcess(await context.manager.addProcess(input.name, input.definition));
|
|
133
135
|
});
|
|
134
136
|
const startProcess = os.processes.start.handler(async ({ input, context }) => {
|
|
135
|
-
return serializeProcess(context.manager.startProcessByTarget(input.target));
|
|
137
|
+
return serializeProcess(await context.manager.startProcessByTarget(input.target));
|
|
136
138
|
});
|
|
137
139
|
const stopProcess = os.processes.stop.handler(async ({ input, context }) => {
|
|
138
140
|
return serializeProcess(await context.manager.stopProcessByTarget(input.target));
|
|
@@ -211,6 +213,45 @@ const router = os.router({
|
|
|
211
213
|
}
|
|
212
214
|
});
|
|
213
215
|
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/port-utils.ts
|
|
218
|
+
const execAsync = promisify(exec);
|
|
219
|
+
/**
|
|
220
|
+
* Kill any process listening on the specified port, including all descendants.
|
|
221
|
+
* Works on macOS, Linux, and Windows.
|
|
222
|
+
*/
|
|
223
|
+
async function killProcessOnPort(port) {
|
|
224
|
+
try {
|
|
225
|
+
const platform = process.platform;
|
|
226
|
+
if (platform === "darwin" || platform === "linux") {
|
|
227
|
+
const { stdout } = await execAsync(`lsof -ti tcp:${port}`);
|
|
228
|
+
const pids = stdout.trim().split("\n").filter(Boolean).map((p) => parseInt(p, 10)).filter((p) => !isNaN(p));
|
|
229
|
+
if (pids.length === 0) return false;
|
|
230
|
+
for (const pid of pids) try {
|
|
231
|
+
await treeKill(pid, "SIGKILL");
|
|
232
|
+
} catch {}
|
|
233
|
+
return true;
|
|
234
|
+
} else if (platform === "win32") {
|
|
235
|
+
const { stdout } = await execAsync(`netstat -ano | findstr :${port} | findstr LISTENING`);
|
|
236
|
+
const lines = stdout.trim().split("\n").filter(Boolean);
|
|
237
|
+
if (lines.length === 0) return false;
|
|
238
|
+
const pids = /* @__PURE__ */ new Set();
|
|
239
|
+
for (const line of lines) {
|
|
240
|
+
const parts = line.trim().split(/\s+/);
|
|
241
|
+
const pid = parseInt(parts[parts.length - 1], 10);
|
|
242
|
+
if (!isNaN(pid) && pid !== 0) pids.add(pid);
|
|
243
|
+
}
|
|
244
|
+
for (const pid of pids) try {
|
|
245
|
+
await treeKill(pid, "SIGKILL");
|
|
246
|
+
} catch {}
|
|
247
|
+
return pids.size > 0;
|
|
248
|
+
}
|
|
249
|
+
return false;
|
|
250
|
+
} catch {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
214
255
|
//#endregion
|
|
215
256
|
//#region src/manager.ts
|
|
216
257
|
const HttpServerConfigSchema = v.object({
|
|
@@ -234,7 +275,8 @@ const RestartingProcessEntrySchema = v.object({
|
|
|
234
275
|
definition: ProcessDefinitionSchema,
|
|
235
276
|
options: v.optional(RestartingProcessOptionsSchema),
|
|
236
277
|
envFile: v.optional(v.string()),
|
|
237
|
-
envReloadDelay: v.optional(EnvReloadDelaySchema)
|
|
278
|
+
envReloadDelay: v.optional(EnvReloadDelaySchema),
|
|
279
|
+
port: v.optional(v.number())
|
|
238
280
|
});
|
|
239
281
|
const TaskEntrySchema = v.object({
|
|
240
282
|
name: v.string(),
|
|
@@ -268,6 +310,7 @@ var Manager = class {
|
|
|
268
310
|
processEnvReloadConfig = /* @__PURE__ */ new Map();
|
|
269
311
|
envReloadTimers = /* @__PURE__ */ new Map();
|
|
270
312
|
envChangeUnsubscribe = null;
|
|
313
|
+
processPortConfig = /* @__PURE__ */ new Map();
|
|
271
314
|
signalHandlers = /* @__PURE__ */ new Map();
|
|
272
315
|
shutdownPromise = null;
|
|
273
316
|
isShuttingDown = false;
|
|
@@ -322,6 +365,14 @@ var Manager = class {
|
|
|
322
365
|
cronLogFile(name) {
|
|
323
366
|
return join(this.logDir, "cron", `${name}.log`);
|
|
324
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Kill any process running on the configured port for a process
|
|
370
|
+
*/
|
|
371
|
+
async killPortForProcess(processName) {
|
|
372
|
+
const port = this.processPortConfig.get(processName);
|
|
373
|
+
if (port === void 0) return;
|
|
374
|
+
if (await killProcessOnPort(port)) this.logger.info(`Killed process on port ${port} before starting "${processName}"`);
|
|
375
|
+
}
|
|
325
376
|
ensureLogDirs() {
|
|
326
377
|
mkdirSync(this.logDir, { recursive: true });
|
|
327
378
|
mkdirSync(join(this.logDir, "process"), { recursive: true });
|
|
@@ -455,9 +506,10 @@ var Manager = class {
|
|
|
455
506
|
/**
|
|
456
507
|
* Start a restarting process by target
|
|
457
508
|
*/
|
|
458
|
-
startProcessByTarget(target) {
|
|
509
|
+
async startProcessByTarget(target) {
|
|
459
510
|
const proc = this.getProcessByTarget(target);
|
|
460
511
|
if (!proc) throw new Error(`Process not found: ${target}`);
|
|
512
|
+
await this.killPortForProcess(proc.name);
|
|
461
513
|
proc.start();
|
|
462
514
|
return proc;
|
|
463
515
|
}
|
|
@@ -476,6 +528,7 @@ var Manager = class {
|
|
|
476
528
|
async restartProcessByTarget(target, force = false) {
|
|
477
529
|
const proc = this.getProcessByTarget(target);
|
|
478
530
|
if (!proc) throw new Error(`Process not found: ${target}`);
|
|
531
|
+
await this.killPortForProcess(proc.name);
|
|
479
532
|
await proc.restart(force);
|
|
480
533
|
return proc;
|
|
481
534
|
}
|
|
@@ -533,11 +586,15 @@ var Manager = class {
|
|
|
533
586
|
/**
|
|
534
587
|
* Add a restarting process at runtime
|
|
535
588
|
*/
|
|
536
|
-
addProcess(name, definition, options, envReloadDelay) {
|
|
589
|
+
async addProcess(name, definition, options, envReloadDelay, port) {
|
|
537
590
|
if (this.restartingProcesses.has(name)) throw new Error(`Process "${name}" already exists`);
|
|
538
591
|
const processLogger = this.logger.child(name, { logFile: this.processLogFile(name) });
|
|
539
592
|
const restartingProcess = new RestartingProcess(name, this.applyDefaults(name, definition), options ?? DEFAULT_RESTART_OPTIONS, processLogger);
|
|
540
593
|
this.restartingProcesses.set(name, restartingProcess);
|
|
594
|
+
if (port !== void 0) {
|
|
595
|
+
this.processPortConfig.set(name, port);
|
|
596
|
+
await this.killPortForProcess(name);
|
|
597
|
+
}
|
|
541
598
|
restartingProcess.start();
|
|
542
599
|
this.processEnvReloadConfig.set(name, envReloadDelay ?? 5e3);
|
|
543
600
|
this.logger.info(`Added and started restarting process: ${name}`);
|
|
@@ -608,6 +665,10 @@ var Manager = class {
|
|
|
608
665
|
const processLogger = this.logger.child(entry.name, { logFile: this.processLogFile(entry.name) });
|
|
609
666
|
const restartingProcess = new RestartingProcess(entry.name, this.applyDefaults(entry.name, entry.definition, entry.envFile), entry.options ?? DEFAULT_RESTART_OPTIONS, processLogger);
|
|
610
667
|
this.restartingProcesses.set(entry.name, restartingProcess);
|
|
668
|
+
if (entry.port !== void 0) {
|
|
669
|
+
this.processPortConfig.set(entry.name, entry.port);
|
|
670
|
+
await this.killPortForProcess(entry.name);
|
|
671
|
+
}
|
|
611
672
|
restartingProcess.start();
|
|
612
673
|
this.processEnvReloadConfig.set(entry.name, entry.envReloadDelay ?? 5e3);
|
|
613
674
|
this.logger.info(`Started restarting process: ${entry.name}`);
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["oc","ocBase","processes","tasks","crons","getCwd"],"sources":["../src/api/contract.ts","../src/api/server.ts","../src/manager.ts","../src/cli.ts"],"sourcesContent":["import { oc as ocBase } from \"@orpc/contract\";\nimport * as v from \"valibot\";\nimport { ProcessDefinitionSchema } from \"../lazy-process.ts\";\nimport { RestartingProcessStateSchema } from \"../restarting-process.ts\";\nimport { CronProcessStateSchema } from \"../cron-process.ts\";\nimport { TaskStateSchema } from \"../task-list.ts\";\n\n// Re-export schemas for use in other modules\nexport { ProcessDefinitionSchema } from \"../lazy-process.ts\";\nexport { RestartingProcessStateSchema } from \"../restarting-process.ts\";\nexport { CronProcessStateSchema } from \"../cron-process.ts\";\nexport { TaskStateSchema } from \"../task-list.ts\";\n\nconst oc = ocBase.$input(v.void());\n\n// Resource target (name or index)\nconst ResourceTarget = v.union([v.string(), v.number()]);\n\n// Manager state schema\nexport const ManagerStateSchema = v.picklist([\n \"idle\",\n \"initializing\",\n \"running\",\n \"stopping\",\n \"stopped\",\n]);\n\nexport type ManagerState = v.InferOutput<typeof ManagerStateSchema>;\n\n// Manager status response\nexport const ManagerStatusSchema = v.object({\n state: ManagerStateSchema,\n processCount: v.number(),\n cronCount: v.number(),\n taskCount: v.number(),\n});\n\nexport type ManagerStatus = v.InferOutput<typeof ManagerStatusSchema>;\n\n// API response schemas\nexport const RestartingProcessInfoSchema = v.object({\n name: v.string(),\n state: RestartingProcessStateSchema,\n restarts: v.number(),\n});\n\nexport type RestartingProcessInfo = v.InferOutput<typeof RestartingProcessInfoSchema>;\n\nexport const CronProcessInfoSchema = v.object({\n name: v.string(),\n state: CronProcessStateSchema,\n runCount: v.number(),\n failCount: v.number(),\n nextRun: v.nullable(v.string()), // ISO date string\n});\n\nexport type CronProcessInfo = v.InferOutput<typeof CronProcessInfoSchema>;\n\nexport const TaskEntryInfoSchema = v.object({\n id: v.string(),\n state: TaskStateSchema,\n processNames: v.array(v.string()),\n});\n\nexport type TaskEntryInfo = v.InferOutput<typeof TaskEntryInfoSchema>;\n\n// API contract\nexport const manager = {\n status: oc.output(ManagerStatusSchema),\n};\n\nexport const processes = {\n get: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n list: oc.output(v.array(RestartingProcessInfoSchema)),\n add: oc\n .input(v.object({ name: v.string(), definition: ProcessDefinitionSchema }))\n .output(RestartingProcessInfoSchema),\n start: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n stop: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n restart: oc\n .input(v.object({ target: ResourceTarget, force: v.optional(v.boolean()) }))\n .output(RestartingProcessInfoSchema),\n reload: oc\n .input(\n v.object({\n target: ResourceTarget,\n definition: ProcessDefinitionSchema,\n restartImmediately: v.optional(v.boolean()),\n }),\n )\n .output(RestartingProcessInfoSchema),\n remove: oc.input(v.object({ target: ResourceTarget })).output(v.object({ success: v.boolean() })),\n};\n\nexport const tasks = {\n get: oc.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema),\n list: oc.output(v.array(TaskEntryInfoSchema)),\n add: oc\n .input(v.object({ name: v.string(), definition: ProcessDefinitionSchema }))\n .output(TaskEntryInfoSchema),\n remove: oc.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema),\n};\n\nexport const crons = {\n get: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n list: oc.output(v.array(CronProcessInfoSchema)),\n trigger: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n start: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n stop: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n};\n\nexport const api = {\n manager,\n processes,\n tasks,\n crons,\n};\n","import { implement } from \"@orpc/server\";\nimport {\n api,\n type RestartingProcessInfo,\n type CronProcessInfo,\n type TaskEntryInfo,\n type ManagerStatus,\n} from \"./contract.ts\";\nimport type { Manager } from \"../manager.ts\";\nimport type { RestartingProcess } from \"../restarting-process.ts\";\nimport type { CronProcess } from \"../cron-process.ts\";\n\nconst os = implement(api).$context<{ manager: Manager }>();\n\n// Helper to serialize a RestartingProcess to API response\nfunction serializeProcess(proc: RestartingProcess): RestartingProcessInfo {\n return {\n name: proc.name,\n state: proc.state,\n restarts: proc.restarts,\n };\n}\n\n// Helper to serialize a CronProcess to API response\nfunction serializeCron(cron: CronProcess): CronProcessInfo {\n return {\n name: cron.name,\n state: cron.state,\n runCount: cron.runCount,\n failCount: cron.failCount,\n nextRun: cron.nextRun?.toISOString() ?? null,\n };\n}\n\n// Manager handlers\nconst managerStatus = os.manager.status.handler(async ({ context }): Promise<ManagerStatus> => {\n const manager = context.manager;\n const taskList = manager.getTaskList();\n return {\n state: manager.state,\n processCount: manager.getRestartingProcesses().size,\n cronCount: manager.getCronProcesses().size,\n taskCount: taskList?.tasks.length ?? 0,\n };\n});\n\n// Processes handlers\nconst getProcess = os.processes.get.handler(async ({ input, context }) => {\n const proc = context.manager.getProcessByTarget(input.target);\n if (!proc) {\n throw new Error(`Process not found: ${input.target}`);\n }\n return serializeProcess(proc);\n});\n\nconst listProcesses = os.processes.list.handler(async ({ context }) => {\n const processes = Array.from(context.manager.getRestartingProcesses().values());\n return processes.map(serializeProcess);\n});\n\nconst addProcess = os.processes.add.handler(async ({ input, context }) => {\n const proc = context.manager.addProcess(input.name, input.definition);\n return serializeProcess(proc);\n});\n\nconst startProcess = os.processes.start.handler(async ({ input, context }) => {\n const proc = context.manager.startProcessByTarget(input.target);\n return serializeProcess(proc);\n});\n\nconst stopProcess = os.processes.stop.handler(async ({ input, context }) => {\n const proc = await context.manager.stopProcessByTarget(input.target);\n return serializeProcess(proc);\n});\n\nconst restartProcess = os.processes.restart.handler(async ({ input, context }) => {\n const proc = await context.manager.restartProcessByTarget(input.target, input.force);\n return serializeProcess(proc);\n});\n\nconst reloadProcess = os.processes.reload.handler(async ({ input, context }) => {\n const proc = await context.manager.reloadProcessByTarget(input.target, input.definition, {\n restartImmediately: input.restartImmediately,\n });\n return serializeProcess(proc);\n});\n\nconst removeProcess = os.processes.remove.handler(async ({ input, context }) => {\n await context.manager.removeProcessByTarget(input.target);\n return { success: true };\n});\n\n// Crons handlers\nconst getCron = os.crons.get.handler(async ({ input, context }) => {\n const cron = context.manager.getCronByTarget(input.target);\n if (!cron) {\n throw new Error(`Cron not found: ${input.target}`);\n }\n return serializeCron(cron);\n});\n\nconst listCrons = os.crons.list.handler(async ({ context }) => {\n const crons = Array.from(context.manager.getCronProcesses().values());\n return crons.map(serializeCron);\n});\n\nconst triggerCron = os.crons.trigger.handler(async ({ input, context }) => {\n const cron = await context.manager.triggerCronByTarget(input.target);\n return serializeCron(cron);\n});\n\nconst startCron = os.crons.start.handler(async ({ input, context }) => {\n const cron = context.manager.startCronByTarget(input.target);\n return serializeCron(cron);\n});\n\nconst stopCron = os.crons.stop.handler(async ({ input, context }) => {\n const cron = await context.manager.stopCronByTarget(input.target);\n return serializeCron(cron);\n});\n\n// Tasks handlers\nconst getTask = os.tasks.get.handler(async ({ input, context }) => {\n const task = context.manager.getTaskByTarget(input.target);\n if (!task) {\n throw new Error(`Task not found: ${input.target}`);\n }\n return task as TaskEntryInfo;\n});\n\nconst listTasks = os.tasks.list.handler(async ({ context }) => {\n const taskList = context.manager.getTaskList();\n if (!taskList) {\n return [];\n }\n return taskList.tasks.map((t) => ({\n id: t.id,\n state: t.state,\n processNames: t.processes.map((p) => p.name),\n })) as TaskEntryInfo[];\n});\n\nconst addTask = os.tasks.add.handler(async ({ input, context }) => {\n const task = context.manager.addTask(input.name, input.definition);\n return task as TaskEntryInfo;\n});\n\nconst removeTask = os.tasks.remove.handler(async ({ input, context }) => {\n const task = context.manager.removeTaskByTarget(input.target);\n return task as TaskEntryInfo;\n});\n\nexport const router = os.router({\n manager: {\n status: managerStatus,\n },\n processes: {\n add: addProcess,\n get: getProcess,\n list: listProcesses,\n start: startProcess,\n stop: stopProcess,\n restart: restartProcess,\n reload: reloadProcess,\n remove: removeProcess,\n },\n crons: {\n get: getCron,\n list: listCrons,\n trigger: triggerCron,\n start: startCron,\n stop: stopCron,\n },\n tasks: {\n get: getTask,\n list: listTasks,\n add: addTask,\n remove: removeTask,\n },\n});\n","import * as v from \"valibot\";\nimport { join } from \"node:path\";\nimport { cwd as getCwd } from \"node:process\";\nimport { mkdirSync } from \"node:fs\";\nimport { ProcessDefinitionSchema, type ProcessDefinition } from \"./lazy-process.ts\";\nimport type { Logger } from \"./logger.ts\";\nimport { TaskList, type NamedProcessDefinition } from \"./task-list.ts\";\nimport { CronProcess, CronProcessOptionsSchema } from \"./cron-process.ts\";\nimport {\n RestartingProcess,\n RestartingProcessOptionsSchema,\n type RestartingProcessOptions,\n} from \"./restarting-process.ts\";\nimport { EnvManager } from \"./env-manager.ts\";\n\n// Valibot schemas\n\n// HTTP server configuration schema\nexport const HttpServerConfigSchema = v.object({\n host: v.optional(v.string()),\n port: v.optional(v.number()),\n authToken: v.optional(v.string()),\n});\n\nexport type HttpServerConfig = v.InferOutput<typeof HttpServerConfigSchema>;\n\n// Cron process entry schema\nexport const CronProcessEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n options: CronProcessOptionsSchema,\n envFile: v.optional(v.string()),\n});\n\nexport type CronProcessEntry = v.InferOutput<typeof CronProcessEntrySchema>;\n\n// Env reload delay schema - can be number (ms), \"immediately\"/true, or false for disabled\nexport const EnvReloadDelaySchema = v.union([v.number(), v.boolean(), v.literal(\"immediately\")]);\n\nexport type EnvReloadDelay = v.InferOutput<typeof EnvReloadDelaySchema>;\n\n// Restarting process entry schema\nexport const RestartingProcessEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n options: v.optional(RestartingProcessOptionsSchema),\n envFile: v.optional(v.string()),\n envReloadDelay: v.optional(EnvReloadDelaySchema), // Default 5000ms\n});\n\nexport type RestartingProcessEntry = v.InferOutput<typeof RestartingProcessEntrySchema>;\n\n// Task entry schema with envFile\nexport const TaskEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n envFile: v.optional(v.string()),\n});\n\nexport type TaskEntry = v.InferOutput<typeof TaskEntrySchema>;\n\n// Main manager configuration schema\nexport const ManagerConfigSchema = v.object({\n http: v.optional(HttpServerConfigSchema),\n cwd: v.optional(v.string()),\n logDir: v.optional(v.string()),\n env: v.optional(v.record(v.string(), v.string())),\n envFiles: v.optional(v.record(v.string(), v.string())),\n tasks: v.optional(v.array(TaskEntrySchema)),\n crons: v.optional(v.array(CronProcessEntrySchema)),\n processes: v.optional(v.array(RestartingProcessEntrySchema)),\n});\n\nexport type ManagerConfig = v.InferOutput<typeof ManagerConfigSchema>;\n\n// Default restart policy when not specified\nconst DEFAULT_RESTART_OPTIONS = {\n restartPolicy: \"always\" as const,\n};\n\n// Hardcoded shutdown configuration\nconst SHUTDOWN_TIMEOUT_MS = 15000;\nconst SHUTDOWN_SIGNALS: NodeJS.Signals[] = [\"SIGINT\", \"SIGTERM\"];\nconst SHUTDOWN_EXIT_CODE = 0;\n\n// Manager state\nexport type ManagerState =\n | \"idle\" // Not started\n | \"initializing\" // Running task list\n | \"running\" // All processes running\n | \"stopping\" // Stopping all processes\n | \"stopped\"; // Fully stopped\n\nexport class Manager {\n private config: ManagerConfig;\n private logger: Logger;\n private envManager: EnvManager;\n private envFileKeyByProcess: Map<string, string> = new Map();\n\n private _state: ManagerState = \"idle\";\n private taskList: TaskList | null = null;\n private cronProcesses: Map<string, CronProcess> = new Map();\n private restartingProcesses: Map<string, RestartingProcess> = new Map();\n private logDir: string;\n\n // Env reload tracking\n private processEnvReloadConfig: Map<string, EnvReloadDelay> = new Map();\n private envReloadTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n private envChangeUnsubscribe: (() => void) | null = null;\n\n // Shutdown handling\n private signalHandlers: Map<NodeJS.Signals, () => void> = new Map();\n private shutdownPromise: Promise<void> | null = null;\n private isShuttingDown: boolean = false;\n\n constructor(config: ManagerConfig, logger: Logger) {\n this.config = config;\n this.logger = logger;\n this.logDir = config.logDir ?? join(getCwd(), \"logs\");\n this.ensureLogDirs();\n // Initialize EnvManager with watching enabled\n this.envManager = new EnvManager({\n cwd: config.cwd,\n files: config.envFiles,\n watch: true,\n });\n\n // Register env change handler\n this.envChangeUnsubscribe = this.envManager.onChange((changedKeys) => {\n this.handleEnvChange(changedKeys);\n });\n\n // Automatically register shutdown handlers\n this.registerShutdownHandlers();\n }\n\n /**\n * Merge global env with process-specific env and apply cwd inheritance\n * Merge order: .env (global), config.env (global), .env.<processName>, processEnvFile, definition.env\n */\n private applyDefaults(\n processName: string,\n definition: ProcessDefinition,\n envFile?: string,\n ): ProcessDefinition {\n // Start with env from .env file (global)\n const envFromFiles = this.envManager.getEnvVars(processName);\n\n // Build the env file map for this specific process if envFile is provided\n let envFromCustomFile: Record<string, string> = {};\n if (envFile) {\n let key = this.envFileKeyByProcess.get(processName);\n if (!key) {\n key = `custom:${processName}`;\n this.envFileKeyByProcess.set(processName, key);\n this.envManager.registerFile(key, envFile);\n }\n envFromCustomFile = this.envManager.getEnvForKey(key);\n }\n\n return {\n ...definition,\n cwd: definition.cwd ?? this.config.cwd,\n env: {\n ...envFromFiles, // .env (global) + .env.<processName>\n ...this.config.env, // Global env from config\n ...envFromCustomFile, // Custom env file if specified\n ...definition.env, // Process-specific env overrides\n },\n };\n }\n\n private processLogFile(name: string): string {\n return join(this.logDir, \"process\", `${name}.log`);\n }\n\n private taskLogFile(name: string): string {\n return join(this.logDir, \"tasks\", `${name}.log`);\n }\n\n private cronLogFile(name: string): string {\n return join(this.logDir, \"cron\", `${name}.log`);\n }\n\n private ensureLogDirs(): void {\n mkdirSync(this.logDir, { recursive: true });\n mkdirSync(join(this.logDir, \"process\"), { recursive: true });\n mkdirSync(join(this.logDir, \"tasks\"), { recursive: true });\n mkdirSync(join(this.logDir, \"cron\"), { recursive: true });\n }\n\n /**\n * Handle env file changes\n */\n private handleEnvChange(changedKeys: string[]): void {\n if (this._state !== \"running\") {\n return; // Only handle changes when manager is running\n }\n\n this.logger.info(`Env files changed for keys: ${changedKeys.join(\", \")}`);\n\n // Check which processes are affected\n const affectedProcesses = new Set<string>();\n\n for (const key of changedKeys) {\n // Global key affects all processes\n if (key === \"global\") {\n for (const processName of this.restartingProcesses.keys()) {\n affectedProcesses.add(processName);\n }\n } else {\n // Specific key affects matching process\n if (this.restartingProcesses.has(key)) {\n affectedProcesses.add(key);\n }\n\n for (const [processName, customKey] of this.envFileKeyByProcess.entries()) {\n if (customKey === key && this.restartingProcesses.has(processName)) {\n affectedProcesses.add(processName);\n }\n }\n }\n }\n\n // Schedule restarts for affected processes\n for (const processName of affectedProcesses) {\n const reloadDelay = this.processEnvReloadConfig.get(processName);\n\n // Skip if reload is disabled for this process\n if (reloadDelay === false) {\n continue;\n }\n\n this.scheduleProcessReload(processName, reloadDelay);\n }\n }\n\n /**\n * Schedule a process reload with debouncing\n */\n private scheduleProcessReload(processName: string, reloadDelay?: EnvReloadDelay): void {\n // Clear existing timer if any\n const existingTimer = this.envReloadTimers.get(processName);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Determine delay in ms\n let delayMs: number;\n if (reloadDelay === false) {\n return; // Should not happen, but guard anyway\n } else if (reloadDelay === true || reloadDelay === \"immediately\") {\n delayMs = 0;\n } else if (typeof reloadDelay === \"number\") {\n delayMs = reloadDelay;\n } else {\n delayMs = 5000; // Default 5 seconds\n }\n\n this.logger.info(`Scheduling reload for process \"${processName}\" in ${delayMs}ms`);\n\n const timer = setTimeout(async () => {\n await this.reloadProcessEnv(processName);\n this.envReloadTimers.delete(processName);\n }, delayMs);\n\n this.envReloadTimers.set(processName, timer);\n }\n\n /**\n * Reload a process with updated env vars\n */\n private async reloadProcessEnv(processName: string): Promise<void> {\n const proc = this.restartingProcesses.get(processName);\n if (!proc) {\n this.logger.warn(`Process \"${processName}\" not found for env reload`);\n return;\n }\n\n this.logger.info(`Reloading process \"${processName}\" due to env change`);\n\n // Get the original config for this process\n const processConfig = this.config.processes?.find((p) => p.name === processName);\n if (!processConfig) {\n this.logger.warn(`Process config for \"${processName}\" not found`);\n return;\n }\n\n // Rebuild definition with updated env\n const updatedDefinition = this.applyDefaults(\n processName,\n processConfig.definition,\n processConfig.envFile,\n );\n\n // Reload the process (graceful restart)\n await proc.reload(updatedDefinition, true);\n }\n\n get state(): ManagerState {\n return this._state;\n }\n\n /**\n * Get all cron processes (read-only access)\n */\n getCronProcesses(): ReadonlyMap<string, CronProcess> {\n return this.cronProcesses;\n }\n\n /**\n * Get a specific cron process by name\n */\n getCronProcess(name: string): CronProcess | undefined {\n return this.cronProcesses.get(name);\n }\n\n /**\n * Get all restarting processes (read-only access)\n */\n getRestartingProcesses(): ReadonlyMap<string, RestartingProcess> {\n return this.restartingProcesses;\n }\n\n /**\n * Get a specific restarting process by name\n */\n getRestartingProcess(name: string): RestartingProcess | undefined {\n return this.restartingProcesses.get(name);\n }\n\n /**\n * Get the task list (read-only access)\n */\n getTaskList(): TaskList | null {\n return this.taskList;\n }\n\n /**\n * Get a restarting process by name or index\n */\n getProcessByTarget(target: string | number): RestartingProcess | undefined {\n if (typeof target === \"string\") {\n return this.restartingProcesses.get(target);\n }\n const entries = Array.from(this.restartingProcesses.values());\n return entries[target];\n }\n\n /**\n * Get a cron process by name or index\n */\n getCronByTarget(target: string | number): CronProcess | undefined {\n if (typeof target === \"string\") {\n return this.cronProcesses.get(target);\n }\n const entries = Array.from(this.cronProcesses.values());\n return entries[target];\n }\n\n /**\n * Get a task by id or index\n */\n getTaskByTarget(\n target: string | number,\n ): { id: string; state: string; processNames: string[] } | undefined {\n if (!this.taskList) return undefined;\n const tasks = this.taskList.tasks;\n\n if (typeof target === \"string\") {\n const task = tasks.find((t) => t.id === target);\n if (!task) return undefined;\n return {\n id: task.id,\n state: task.state,\n processNames: task.processes.map((p) => p.name),\n };\n }\n\n const task = tasks[target];\n if (!task) return undefined;\n return {\n id: task.id,\n state: task.state,\n processNames: task.processes.map((p) => p.name),\n };\n }\n\n /**\n * Start a restarting process by target\n */\n startProcessByTarget(target: string | number): RestartingProcess {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n proc.start();\n return proc;\n }\n\n /**\n * Stop a restarting process by target\n */\n async stopProcessByTarget(target: string | number, timeout?: number): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n await proc.stop(timeout);\n return proc;\n }\n\n /**\n * Restart a restarting process by target\n */\n async restartProcessByTarget(\n target: string | number,\n force: boolean = false,\n ): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n await proc.restart(force);\n return proc;\n }\n\n /**\n * Reload a restarting process with new definition\n */\n async reloadProcessByTarget(\n target: string | number,\n newDefinition: ProcessDefinition,\n options?: {\n restartImmediately?: boolean;\n updateOptions?: Partial<RestartingProcessOptions>;\n },\n ): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n\n // Apply global defaults to new definition\n const definitionWithDefaults = this.applyDefaults(proc.name, newDefinition);\n\n // Update options if provided\n if (options?.updateOptions) {\n proc.updateOptions(options.updateOptions);\n }\n\n // Reload with new definition\n await proc.reload(definitionWithDefaults, options?.restartImmediately ?? true);\n this.logger.info(`Reloaded process: ${proc.name}`);\n return proc;\n }\n\n /**\n * Remove a restarting process by target\n */\n async removeProcessByTarget(target: string | number, timeout?: number): Promise<void> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n\n // Stop the process first\n await proc.stop(timeout);\n\n // Remove from the map\n this.restartingProcesses.delete(proc.name);\n this.logger.info(`Removed process: ${proc.name}`);\n }\n\n /**\n * Add a task to the task list\n * Creates the task list if it doesn't exist and starts it\n */\n addTask(\n name: string,\n definition: ProcessDefinition,\n ): { id: string; state: string; processNames: string[] } {\n if (!this.taskList) {\n const taskListLogger = this.logger.child(\"tasks\", {\n logFile: this.taskLogFile(\"tasks\"),\n });\n this.taskList = new TaskList(\"runtime\", taskListLogger, undefined, (processName) => {\n return this.taskLogFile(processName);\n });\n }\n\n const namedProcess: NamedProcessDefinition = {\n name,\n process: this.applyDefaults(name, definition),\n };\n const id = this.taskList.addTask(namedProcess);\n\n // Start the task list if it's idle so the task runs immediately\n if (this.taskList.state === \"idle\") {\n this.taskList.start();\n }\n\n return {\n id,\n state: \"pending\",\n processNames: [name],\n };\n }\n\n removeTaskByTarget(target: string | number): {\n id: string;\n state: string;\n processNames: string[];\n } {\n if (!this.taskList) {\n throw new Error(`Task list not initialized`);\n }\n\n const removed = this.taskList.removeTaskByTarget(target);\n return {\n id: removed.id,\n state: removed.state,\n processNames: removed.processes.map((p) => p.name),\n };\n }\n\n /**\n * Add a restarting process at runtime\n */\n addProcess(\n name: string,\n definition: ProcessDefinition,\n options?: RestartingProcessOptions,\n envReloadDelay?: EnvReloadDelay,\n ): RestartingProcess {\n if (this.restartingProcesses.has(name)) {\n throw new Error(`Process \"${name}\" already exists`);\n }\n\n const processLogger = this.logger.child(name, { logFile: this.processLogFile(name) });\n const restartingProcess = new RestartingProcess(\n name,\n this.applyDefaults(name, definition),\n options ?? DEFAULT_RESTART_OPTIONS,\n processLogger,\n );\n this.restartingProcesses.set(name, restartingProcess);\n restartingProcess.start();\n\n // Track env reload config for this process\n this.processEnvReloadConfig.set(name, envReloadDelay ?? 5000);\n\n this.logger.info(`Added and started restarting process: ${name}`);\n return restartingProcess;\n }\n\n /**\n * Trigger a cron process by target\n */\n async triggerCronByTarget(target: string | number): Promise<CronProcess> {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n await cron.trigger();\n return cron;\n }\n\n /**\n * Start a cron process by target\n */\n startCronByTarget(target: string | number): CronProcess {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n cron.start();\n return cron;\n }\n\n /**\n * Stop a cron process by target\n */\n async stopCronByTarget(target: string | number, timeout?: number): Promise<CronProcess> {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n await cron.stop(timeout);\n return cron;\n }\n\n /**\n * Start the manager:\n * 1. Run task list (if configured) and wait for completion\n * 2. Create and start all cron/restarting processes\n */\n async start(): Promise<void> {\n if (this._state !== \"idle\" && this._state !== \"stopped\") {\n throw new Error(`Manager is already ${this._state}`);\n }\n\n this.logger.info(`Starting manager`);\n\n // Phase 1: Run initialization tasks\n if (this.config.tasks && this.config.tasks.length > 0) {\n this._state = \"initializing\";\n this.logger.info(`Running initialization tasks`);\n\n const taskListLogger = this.logger.child(\"tasks\");\n // Apply defaults to all tasks\n const tasksWithDefaults = this.config.tasks.map((task) => ({\n name: task.name,\n process: this.applyDefaults(task.name, task.definition, task.envFile),\n }));\n this.taskList = new TaskList(\"init\", taskListLogger, tasksWithDefaults, (processName) => {\n return this.taskLogFile(processName);\n });\n\n this.taskList.start();\n await this.taskList.waitUntilIdle();\n\n // Check if any tasks failed\n const failedTasks = this.taskList.tasks.filter((t) => t.state === \"failed\");\n if (failedTasks.length > 0) {\n this._state = \"stopped\";\n const failedNames = failedTasks.map((t) => t.id).join(\", \");\n throw new Error(`Initialization failed: tasks [${failedNames}] failed`);\n }\n\n this.logger.info(`Initialization tasks completed`);\n }\n\n // Phase 2: Create and start cron processes\n if (this.config.crons) {\n for (const entry of this.config.crons) {\n const processLogger = this.logger.child(entry.name, {\n logFile: this.cronLogFile(entry.name),\n });\n const cronProcess = new CronProcess(\n entry.name,\n this.applyDefaults(entry.name, entry.definition, entry.envFile),\n entry.options,\n processLogger,\n );\n this.cronProcesses.set(entry.name, cronProcess);\n cronProcess.start();\n this.logger.info(`Started cron process: ${entry.name}`);\n }\n }\n\n // Phase 3: Create and start restarting processes\n if (this.config.processes) {\n for (const entry of this.config.processes) {\n const processLogger = this.logger.child(entry.name, {\n logFile: this.processLogFile(entry.name),\n });\n const restartingProcess = new RestartingProcess(\n entry.name,\n this.applyDefaults(entry.name, entry.definition, entry.envFile),\n entry.options ?? DEFAULT_RESTART_OPTIONS,\n processLogger,\n );\n this.restartingProcesses.set(entry.name, restartingProcess);\n restartingProcess.start();\n\n // Track env reload config for this process\n this.processEnvReloadConfig.set(\n entry.name,\n entry.envReloadDelay ?? 5000, // Default to 5000ms\n );\n\n this.logger.info(`Started restarting process: ${entry.name}`);\n }\n }\n\n this._state = \"running\";\n this.logger.info(\n `Manager started with ${this.cronProcesses.size} cron process(es) and ${this.restartingProcesses.size} restarting process(es)`,\n );\n }\n\n /**\n * Stop all managed processes\n */\n async stop(timeout?: number): Promise<void> {\n if (this._state === \"idle\" || this._state === \"stopped\") {\n this._state = \"stopped\";\n this.unregisterShutdownHandlers();\n return;\n }\n\n this._state = \"stopping\";\n this.logger.info(`Stopping manager`);\n\n // Clear all env reload timers\n for (const timer of this.envReloadTimers.values()) {\n clearTimeout(timer);\n }\n this.envReloadTimers.clear();\n\n // Unsubscribe from env changes\n if (this.envChangeUnsubscribe) {\n this.envChangeUnsubscribe();\n this.envChangeUnsubscribe = null;\n }\n\n // Dispose env manager\n this.envManager.dispose();\n\n // Stop task list if still running\n if (this.taskList) {\n await this.taskList.stop(timeout);\n }\n\n // Stop all cron processes in parallel\n const cronStopPromises = Array.from(this.cronProcesses.values()).map((p) => p.stop(timeout));\n\n // Stop all restarting processes in parallel\n const restartingStopPromises = Array.from(this.restartingProcesses.values()).map((p) =>\n p.stop(timeout),\n );\n\n await Promise.all([...cronStopPromises, ...restartingStopPromises]);\n\n this._state = \"stopped\";\n this.logger.info(`Manager stopped`);\n\n this.unregisterShutdownHandlers();\n }\n\n /**\n * Register signal handlers for graceful shutdown\n * Called automatically by constructor\n */\n private registerShutdownHandlers(): void {\n if (this.signalHandlers.size > 0) {\n this.logger.warn(`Shutdown handlers already registered`);\n return;\n }\n\n for (const signal of SHUTDOWN_SIGNALS) {\n const handler = () => this.handleSignal(signal);\n this.signalHandlers.set(signal, handler);\n process.on(signal, handler);\n this.logger.debug(`Registered handler for ${signal}`);\n }\n\n this.logger.info(`Shutdown handlers registered for signals: ${SHUTDOWN_SIGNALS.join(\", \")}`);\n }\n\n /**\n * Unregister signal handlers for graceful shutdown\n */\n private unregisterShutdownHandlers(): void {\n if (this.signalHandlers.size === 0) {\n return;\n }\n\n for (const [signal, handler] of this.signalHandlers.entries()) {\n process.off(signal, handler);\n this.logger.debug(`Unregistered handler for ${signal}`);\n }\n\n this.signalHandlers.clear();\n }\n\n /**\n * Wait for shutdown to complete (useful for keeping process alive)\n * Resolves when the manager has fully stopped\n */\n async waitForShutdown(): Promise<void> {\n // If already stopped, return immediately\n if (this._state === \"stopped\") {\n return;\n }\n\n // If shutdown is in progress, wait for it\n if (this.shutdownPromise) {\n await this.shutdownPromise;\n return;\n }\n\n // Wait for state to become stopped\n return new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (this._state === \"stopped\") {\n clearInterval(checkInterval);\n resolve();\n }\n }, 100);\n });\n }\n\n /**\n * Trigger graceful shutdown programmatically\n */\n async shutdown(): Promise<void> {\n if (this.isShuttingDown) {\n this.logger.warn(`Shutdown already in progress`);\n if (this.shutdownPromise) {\n await this.shutdownPromise;\n }\n return;\n }\n\n this.isShuttingDown = true;\n this.logger.info(`Initiating graceful shutdown (timeout: ${SHUTDOWN_TIMEOUT_MS}ms)`);\n\n this.shutdownPromise = this.performShutdown();\n await this.shutdownPromise;\n }\n\n private handleSignal(signal: NodeJS.Signals): void {\n this.logger.info(`Received ${signal}, initiating graceful shutdown...`);\n\n // Prevent handling multiple signals\n if (this.isShuttingDown) {\n this.logger.warn(`Shutdown already in progress, ignoring ${signal}`);\n return;\n }\n\n this.isShuttingDown = true;\n this.shutdownPromise = this.performShutdown();\n\n this.shutdownPromise\n .then(() => {\n this.logger.info(`Exiting with code ${SHUTDOWN_EXIT_CODE}`);\n process.exit(SHUTDOWN_EXIT_CODE);\n })\n .catch((err) => {\n this.logger.error(`Shutdown error:`, err);\n process.exit(1);\n });\n }\n\n private async performShutdown(): Promise<void> {\n // Create a timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Shutdown timed out after ${SHUTDOWN_TIMEOUT_MS}ms`));\n }, SHUTDOWN_TIMEOUT_MS);\n });\n\n try {\n // Race between graceful stop and timeout\n await Promise.race([this.stop(SHUTDOWN_TIMEOUT_MS), timeoutPromise]);\n this.logger.info(`Graceful shutdown completed`);\n } catch (err) {\n this.logger.error(`Shutdown error:`, err);\n // Force stop on timeout\n this._state = \"stopped\";\n throw err;\n } finally {\n this.isShuttingDown = false;\n this.shutdownPromise = null;\n }\n }\n}\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { createServer } from \"node:http\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport * as v from \"valibot\";\nimport { router } from \"./api/server.ts\";\nimport { Manager, ManagerConfigSchema } from \"./manager.ts\";\nimport { logger } from \"./logger.ts\";\nimport { tsImport } from \"tsx/esm/api\";\nimport Table from \"cli-table3\";\nimport { createClient } from \"./api/client.ts\";\nimport { ProcessDefinitionSchema } from \"./api/contract.ts\";\n\nconst program = new Command();\n\nprogram\n .name(\"pidnap\")\n .description(\"Process manager with init system capabilities\")\n .version(\"0.0.0-dev.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize and run the process manager with config file\")\n .option(\"-c, --config <path>\", \"Path to config file\", \"pidnap.config.ts\")\n .action(async (options) => {\n const initLogger = logger({ name: \"pidnap\" });\n try {\n // Resolve config file path\n const configPath = resolve(process.cwd(), options.config);\n const configUrl = pathToFileURL(configPath).href;\n\n // Import the config file\n const configModule = await tsImport(configUrl, { parentURL: import.meta.url });\n const rawConfig =\n configModule.default.default || configModule.default || configModule.config || {};\n\n // Parse and validate the config with Valibot\n const config = v.parse(ManagerConfigSchema, rawConfig);\n\n // Extract HTTP config with defaults\n const host = config.http?.host ?? \"localhost\";\n const port = config.http?.port ?? 3000;\n const authToken = config.http?.authToken;\n\n // Create manager with config\n const logDir = config.logDir ?? resolve(process.cwd(), \"logs\");\n const managerLogger = logger({ name: \"pidnap\", logFile: resolve(logDir, \"pidnap.log\") });\n const manager = new Manager(config, managerLogger);\n\n // Setup ORPC server with optional auth token middleware\n const handler = new RPCHandler(router, {\n interceptors: [\n onError((error) => {\n managerLogger.error(error);\n }),\n ],\n });\n\n const server = createServer(async (req, res) => {\n // Check auth token if configured\n if (authToken) {\n const providedToken = req.headers[\"authorization\"]?.replace(\"Bearer \", \"\");\n if (providedToken !== authToken) {\n res.statusCode = 401;\n res.end(\"Unauthorized\");\n return;\n }\n }\n\n const { matched } = await handler.handle(req, res, {\n prefix: \"/rpc\",\n context: { manager },\n });\n if (matched) return;\n res.statusCode = 404;\n res.end(\"Not found\");\n });\n\n server.listen(port, host, async () => {\n managerLogger.info(`pidnap RPC server running on http://${host}:${port}`);\n if (authToken) {\n managerLogger.info(\"Auth token required for API access\");\n }\n\n try {\n await manager.start();\n } catch (err) {\n managerLogger.error(\"Failed to start manager:\", err);\n server.close();\n process.exit(1);\n }\n });\n\n // Wait for shutdown\n await manager.waitForShutdown();\n\n // Close server on shutdown\n server.close();\n } catch (error) {\n initLogger.error(\"Failed to start pidnap:\", error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"status\")\n .description(\"Show manager status\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const status = await client.manager.status();\n\n const table = new Table({ head: [\"State\", \"Processes\", \"Crons\", \"Tasks\"] });\n table.push([status.state, status.processCount, status.cronCount, status.taskCount]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to fetch status:\", error);\n process.exit(1);\n }\n });\n\nconst processes = program.command(\"processes\").description(\"Manage restarting processes\");\n\nprocesses\n .command(\"list\")\n .description(\"List restarting processes\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const processes = await client.processes.list();\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n for (const proc of processes) {\n table.push([proc.name, proc.state, proc.restarts]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list processes:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"get\")\n .description(\"Get a restarting process by name or index\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"add\")\n .description(\"Add a restarting process\")\n .requiredOption(\"-n, --name <name>\", \"Process name\")\n .requiredOption(\"-d, --definition <json>\", \"Process definition JSON\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const definition = parseDefinition(options.definition);\n const proc = await client.processes.add({ name: options.name, definition });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to add process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"start\")\n .description(\"Start a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.start({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to start process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"stop\")\n .description(\"Stop a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.stop({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to stop process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"restart\")\n .description(\"Restart a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-f, --force\", \"Force restart\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.restart({\n target: parseTarget(target),\n force: options.force,\n });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to restart process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"remove\")\n .description(\"Remove a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n await client.processes.remove({ target: parseTarget(target) });\n console.log(\"Process removed\");\n } catch (error) {\n console.error(\"Failed to remove process:\", error);\n process.exit(1);\n }\n });\n\nconst crons = program.command(\"crons\").description(\"Manage cron processes\");\n\ncrons\n .command(\"list\")\n .description(\"List cron processes\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const crons = await client.crons.list();\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n for (const cron of crons) {\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list crons:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"get\")\n .description(\"Get a cron process by name or index\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"trigger\")\n .description(\"Trigger a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.trigger({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to trigger cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"start\")\n .description(\"Start a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.start({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to start cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"stop\")\n .description(\"Stop a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.stop({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to stop cron:\", error);\n process.exit(1);\n }\n });\n\nconst tasks = program.command(\"tasks\").description(\"Manage tasks\");\n\ntasks\n .command(\"list\")\n .description(\"List tasks\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const tasks = await client.tasks.list();\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n for (const task of tasks) {\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list tasks:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"get\")\n .description(\"Get a task by id or index\")\n .argument(\"<target>\", \"Task id or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const task = await client.tasks.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get task:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"add\")\n .description(\"Add a task\")\n .requiredOption(\"-n, --name <name>\", \"Task name\")\n .requiredOption(\"-d, --definition <json>\", \"Process definition JSON\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const definition = parseDefinition(options.definition);\n const task = await client.tasks.add({ name: options.name, definition });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to add task:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"remove\")\n .description(\"Remove a task by id or index\")\n .argument(\"<target>\", \"Task id or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const task = await client.tasks.remove({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to remove task:\", error);\n process.exit(1);\n }\n });\n\nconst TargetSchema = v.union([v.string(), v.number()]);\ntype ProcessDefinition = v.InferOutput<typeof ProcessDefinitionSchema>;\n\nfunction parseTarget(value: string): string | number {\n const asNumber = Number(value);\n return v.parse(TargetSchema, Number.isNaN(asNumber) ? value : asNumber);\n}\n\nfunction parseDefinition(raw: string): ProcessDefinition {\n try {\n const parsed = JSON.parse(raw);\n return v.parse(ProcessDefinitionSchema, parsed);\n } catch (error) {\n console.error(\"Invalid --definition JSON. Expected a ProcessDefinition.\");\n throw error;\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["oc","ocBase","processes","tasks","crons","getCwd"],"sources":["../src/api/contract.ts","../src/api/server.ts","../src/port-utils.ts","../src/manager.ts","../src/cli.ts"],"sourcesContent":["import { oc as ocBase } from \"@orpc/contract\";\nimport * as v from \"valibot\";\nimport { ProcessDefinitionSchema } from \"../lazy-process.ts\";\nimport { RestartingProcessStateSchema } from \"../restarting-process.ts\";\nimport { CronProcessStateSchema } from \"../cron-process.ts\";\nimport { TaskStateSchema } from \"../task-list.ts\";\n\n// Re-export schemas for use in other modules\nexport { ProcessDefinitionSchema } from \"../lazy-process.ts\";\nexport { RestartingProcessStateSchema } from \"../restarting-process.ts\";\nexport { CronProcessStateSchema } from \"../cron-process.ts\";\nexport { TaskStateSchema } from \"../task-list.ts\";\n\nconst oc = ocBase.$input(v.void());\n\n// Resource target (name or index)\nconst ResourceTarget = v.union([v.string(), v.number()]);\n\n// Manager state schema\nexport const ManagerStateSchema = v.picklist([\n \"idle\",\n \"initializing\",\n \"running\",\n \"stopping\",\n \"stopped\",\n]);\n\nexport type ManagerState = v.InferOutput<typeof ManagerStateSchema>;\n\n// Manager status response\nexport const ManagerStatusSchema = v.object({\n state: ManagerStateSchema,\n processCount: v.number(),\n cronCount: v.number(),\n taskCount: v.number(),\n});\n\nexport type ManagerStatus = v.InferOutput<typeof ManagerStatusSchema>;\n\n// API response schemas\nexport const RestartingProcessInfoSchema = v.object({\n name: v.string(),\n state: RestartingProcessStateSchema,\n restarts: v.number(),\n});\n\nexport type RestartingProcessInfo = v.InferOutput<typeof RestartingProcessInfoSchema>;\n\nexport const CronProcessInfoSchema = v.object({\n name: v.string(),\n state: CronProcessStateSchema,\n runCount: v.number(),\n failCount: v.number(),\n nextRun: v.nullable(v.string()), // ISO date string\n});\n\nexport type CronProcessInfo = v.InferOutput<typeof CronProcessInfoSchema>;\n\nexport const TaskEntryInfoSchema = v.object({\n id: v.string(),\n state: TaskStateSchema,\n processNames: v.array(v.string()),\n});\n\nexport type TaskEntryInfo = v.InferOutput<typeof TaskEntryInfoSchema>;\n\n// API contract\nexport const manager = {\n status: oc.output(ManagerStatusSchema),\n};\n\nexport const processes = {\n get: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n list: oc.output(v.array(RestartingProcessInfoSchema)),\n add: oc\n .input(v.object({ name: v.string(), definition: ProcessDefinitionSchema }))\n .output(RestartingProcessInfoSchema),\n start: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n stop: oc.input(v.object({ target: ResourceTarget })).output(RestartingProcessInfoSchema),\n restart: oc\n .input(v.object({ target: ResourceTarget, force: v.optional(v.boolean()) }))\n .output(RestartingProcessInfoSchema),\n reload: oc\n .input(\n v.object({\n target: ResourceTarget,\n definition: ProcessDefinitionSchema,\n restartImmediately: v.optional(v.boolean()),\n }),\n )\n .output(RestartingProcessInfoSchema),\n remove: oc.input(v.object({ target: ResourceTarget })).output(v.object({ success: v.boolean() })),\n};\n\nexport const tasks = {\n get: oc.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema),\n list: oc.output(v.array(TaskEntryInfoSchema)),\n add: oc\n .input(v.object({ name: v.string(), definition: ProcessDefinitionSchema }))\n .output(TaskEntryInfoSchema),\n remove: oc.input(v.object({ target: ResourceTarget })).output(TaskEntryInfoSchema),\n};\n\nexport const crons = {\n get: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n list: oc.output(v.array(CronProcessInfoSchema)),\n trigger: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n start: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n stop: oc.input(v.object({ target: ResourceTarget })).output(CronProcessInfoSchema),\n};\n\nexport const api = {\n manager,\n processes,\n tasks,\n crons,\n};\n","import { implement } from \"@orpc/server\";\nimport {\n api,\n type RestartingProcessInfo,\n type CronProcessInfo,\n type TaskEntryInfo,\n type ManagerStatus,\n} from \"./contract.ts\";\nimport type { Manager } from \"../manager.ts\";\nimport type { RestartingProcess } from \"../restarting-process.ts\";\nimport type { CronProcess } from \"../cron-process.ts\";\n\nconst os = implement(api).$context<{ manager: Manager }>();\n\n// Helper to serialize a RestartingProcess to API response\nfunction serializeProcess(proc: RestartingProcess): RestartingProcessInfo {\n return {\n name: proc.name,\n state: proc.state,\n restarts: proc.restarts,\n };\n}\n\n// Helper to serialize a CronProcess to API response\nfunction serializeCron(cron: CronProcess): CronProcessInfo {\n return {\n name: cron.name,\n state: cron.state,\n runCount: cron.runCount,\n failCount: cron.failCount,\n nextRun: cron.nextRun?.toISOString() ?? null,\n };\n}\n\n// Manager handlers\nconst managerStatus = os.manager.status.handler(async ({ context }): Promise<ManagerStatus> => {\n const manager = context.manager;\n const taskList = manager.getTaskList();\n return {\n state: manager.state,\n processCount: manager.getRestartingProcesses().size,\n cronCount: manager.getCronProcesses().size,\n taskCount: taskList?.tasks.length ?? 0,\n };\n});\n\n// Processes handlers\nconst getProcess = os.processes.get.handler(async ({ input, context }) => {\n const proc = context.manager.getProcessByTarget(input.target);\n if (!proc) {\n throw new Error(`Process not found: ${input.target}`);\n }\n return serializeProcess(proc);\n});\n\nconst listProcesses = os.processes.list.handler(async ({ context }) => {\n const processes = Array.from(context.manager.getRestartingProcesses().values());\n return processes.map(serializeProcess);\n});\n\nconst addProcess = os.processes.add.handler(async ({ input, context }) => {\n const proc = await context.manager.addProcess(input.name, input.definition);\n return serializeProcess(proc);\n});\n\nconst startProcess = os.processes.start.handler(async ({ input, context }) => {\n const proc = await context.manager.startProcessByTarget(input.target);\n return serializeProcess(proc);\n});\n\nconst stopProcess = os.processes.stop.handler(async ({ input, context }) => {\n const proc = await context.manager.stopProcessByTarget(input.target);\n return serializeProcess(proc);\n});\n\nconst restartProcess = os.processes.restart.handler(async ({ input, context }) => {\n const proc = await context.manager.restartProcessByTarget(input.target, input.force);\n return serializeProcess(proc);\n});\n\nconst reloadProcess = os.processes.reload.handler(async ({ input, context }) => {\n const proc = await context.manager.reloadProcessByTarget(input.target, input.definition, {\n restartImmediately: input.restartImmediately,\n });\n return serializeProcess(proc);\n});\n\nconst removeProcess = os.processes.remove.handler(async ({ input, context }) => {\n await context.manager.removeProcessByTarget(input.target);\n return { success: true };\n});\n\n// Crons handlers\nconst getCron = os.crons.get.handler(async ({ input, context }) => {\n const cron = context.manager.getCronByTarget(input.target);\n if (!cron) {\n throw new Error(`Cron not found: ${input.target}`);\n }\n return serializeCron(cron);\n});\n\nconst listCrons = os.crons.list.handler(async ({ context }) => {\n const crons = Array.from(context.manager.getCronProcesses().values());\n return crons.map(serializeCron);\n});\n\nconst triggerCron = os.crons.trigger.handler(async ({ input, context }) => {\n const cron = await context.manager.triggerCronByTarget(input.target);\n return serializeCron(cron);\n});\n\nconst startCron = os.crons.start.handler(async ({ input, context }) => {\n const cron = context.manager.startCronByTarget(input.target);\n return serializeCron(cron);\n});\n\nconst stopCron = os.crons.stop.handler(async ({ input, context }) => {\n const cron = await context.manager.stopCronByTarget(input.target);\n return serializeCron(cron);\n});\n\n// Tasks handlers\nconst getTask = os.tasks.get.handler(async ({ input, context }) => {\n const task = context.manager.getTaskByTarget(input.target);\n if (!task) {\n throw new Error(`Task not found: ${input.target}`);\n }\n return task as TaskEntryInfo;\n});\n\nconst listTasks = os.tasks.list.handler(async ({ context }) => {\n const taskList = context.manager.getTaskList();\n if (!taskList) {\n return [];\n }\n return taskList.tasks.map((t) => ({\n id: t.id,\n state: t.state,\n processNames: t.processes.map((p) => p.name),\n })) as TaskEntryInfo[];\n});\n\nconst addTask = os.tasks.add.handler(async ({ input, context }) => {\n const task = context.manager.addTask(input.name, input.definition);\n return task as TaskEntryInfo;\n});\n\nconst removeTask = os.tasks.remove.handler(async ({ input, context }) => {\n const task = context.manager.removeTaskByTarget(input.target);\n return task as TaskEntryInfo;\n});\n\nexport const router = os.router({\n manager: {\n status: managerStatus,\n },\n processes: {\n add: addProcess,\n get: getProcess,\n list: listProcesses,\n start: startProcess,\n stop: stopProcess,\n restart: restartProcess,\n reload: reloadProcess,\n remove: removeProcess,\n },\n crons: {\n get: getCron,\n list: listCrons,\n trigger: triggerCron,\n start: startCron,\n stop: stopCron,\n },\n tasks: {\n get: getTask,\n list: listTasks,\n add: addTask,\n remove: removeTask,\n },\n});\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { treeKill } from \"./tree-kill.ts\";\n\nconst execAsync = promisify(exec);\n\n/**\n * Kill any process listening on the specified port, including all descendants.\n * Works on macOS, Linux, and Windows.\n */\nexport async function killProcessOnPort(port: number): Promise<boolean> {\n try {\n const platform = process.platform;\n\n if (platform === \"darwin\" || platform === \"linux\") {\n // Use lsof to find the process ID listening on the port\n const { stdout } = await execAsync(`lsof -ti tcp:${port}`);\n const pids = stdout\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((p) => parseInt(p, 10))\n .filter((p) => !isNaN(p));\n\n if (pids.length === 0) {\n return false; // No process found on port\n }\n\n // Tree kill all processes found on the port (kills children/grandchildren too)\n for (const pid of pids) {\n try {\n await treeKill(pid, \"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n }\n\n return true;\n } else if (platform === \"win32\") {\n // Windows: use netstat to find PIDs\n const { stdout } = await execAsync(\n `netstat -ano | findstr :${port} | findstr LISTENING`,\n );\n const lines = stdout.trim().split(\"\\n\").filter(Boolean);\n\n if (lines.length === 0) {\n return false;\n }\n\n const pids = new Set<number>();\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n const pid = parseInt(parts[parts.length - 1], 10);\n if (!isNaN(pid) && pid !== 0) {\n pids.add(pid);\n }\n }\n\n // treeKill handles /T flag on Windows\n for (const pid of pids) {\n try {\n await treeKill(pid, \"SIGKILL\");\n } catch {\n // Process may have already exited\n }\n }\n\n return pids.size > 0;\n }\n\n return false;\n } catch {\n // Command failed (e.g., no process on port)\n return false;\n }\n}\n","import * as v from \"valibot\";\nimport { join } from \"node:path\";\nimport { cwd as getCwd } from \"node:process\";\nimport { mkdirSync } from \"node:fs\";\nimport { ProcessDefinitionSchema, type ProcessDefinition } from \"./lazy-process.ts\";\nimport type { Logger } from \"./logger.ts\";\nimport { TaskList, type NamedProcessDefinition } from \"./task-list.ts\";\nimport { CronProcess, CronProcessOptionsSchema } from \"./cron-process.ts\";\nimport {\n RestartingProcess,\n RestartingProcessOptionsSchema,\n type RestartingProcessOptions,\n} from \"./restarting-process.ts\";\nimport { EnvManager } from \"./env-manager.ts\";\nimport { killProcessOnPort } from \"./port-utils.ts\";\n\n// Valibot schemas\n\n// HTTP server configuration schema\nexport const HttpServerConfigSchema = v.object({\n host: v.optional(v.string()),\n port: v.optional(v.number()),\n authToken: v.optional(v.string()),\n});\n\nexport type HttpServerConfig = v.InferOutput<typeof HttpServerConfigSchema>;\n\n// Cron process entry schema\nexport const CronProcessEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n options: CronProcessOptionsSchema,\n envFile: v.optional(v.string()),\n});\n\nexport type CronProcessEntry = v.InferOutput<typeof CronProcessEntrySchema>;\n\n// Env reload delay schema - can be number (ms), \"immediately\"/true, or false for disabled\nexport const EnvReloadDelaySchema = v.union([v.number(), v.boolean(), v.literal(\"immediately\")]);\n\nexport type EnvReloadDelay = v.InferOutput<typeof EnvReloadDelaySchema>;\n\n// Restarting process entry schema\nexport const RestartingProcessEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n options: v.optional(RestartingProcessOptionsSchema),\n envFile: v.optional(v.string()),\n envReloadDelay: v.optional(EnvReloadDelaySchema), // Default 5000ms\n port: v.optional(v.number()), // Kill any process on this port before spawning\n});\n\nexport type RestartingProcessEntry = v.InferOutput<typeof RestartingProcessEntrySchema>;\n\n// Task entry schema with envFile\nexport const TaskEntrySchema = v.object({\n name: v.string(),\n definition: ProcessDefinitionSchema,\n envFile: v.optional(v.string()),\n});\n\nexport type TaskEntry = v.InferOutput<typeof TaskEntrySchema>;\n\n// Main manager configuration schema\nexport const ManagerConfigSchema = v.object({\n http: v.optional(HttpServerConfigSchema),\n cwd: v.optional(v.string()),\n logDir: v.optional(v.string()),\n env: v.optional(v.record(v.string(), v.string())),\n envFiles: v.optional(v.record(v.string(), v.string())),\n tasks: v.optional(v.array(TaskEntrySchema)),\n crons: v.optional(v.array(CronProcessEntrySchema)),\n processes: v.optional(v.array(RestartingProcessEntrySchema)),\n});\n\nexport type ManagerConfig = v.InferOutput<typeof ManagerConfigSchema>;\n\n// Default restart policy when not specified\nconst DEFAULT_RESTART_OPTIONS = {\n restartPolicy: \"always\" as const,\n};\n\n// Hardcoded shutdown configuration\nconst SHUTDOWN_TIMEOUT_MS = 15000;\nconst SHUTDOWN_SIGNALS: NodeJS.Signals[] = [\"SIGINT\", \"SIGTERM\"];\nconst SHUTDOWN_EXIT_CODE = 0;\n\n// Manager state\nexport type ManagerState =\n | \"idle\" // Not started\n | \"initializing\" // Running task list\n | \"running\" // All processes running\n | \"stopping\" // Stopping all processes\n | \"stopped\"; // Fully stopped\n\nexport class Manager {\n private config: ManagerConfig;\n private logger: Logger;\n private envManager: EnvManager;\n private envFileKeyByProcess: Map<string, string> = new Map();\n\n private _state: ManagerState = \"idle\";\n private taskList: TaskList | null = null;\n private cronProcesses: Map<string, CronProcess> = new Map();\n private restartingProcesses: Map<string, RestartingProcess> = new Map();\n private logDir: string;\n\n // Env reload tracking\n private processEnvReloadConfig: Map<string, EnvReloadDelay> = new Map();\n private envReloadTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n private envChangeUnsubscribe: (() => void) | null = null;\n\n // Port tracking for processes\n private processPortConfig: Map<string, number> = new Map();\n\n // Shutdown handling\n private signalHandlers: Map<NodeJS.Signals, () => void> = new Map();\n private shutdownPromise: Promise<void> | null = null;\n private isShuttingDown: boolean = false;\n\n constructor(config: ManagerConfig, logger: Logger) {\n this.config = config;\n this.logger = logger;\n this.logDir = config.logDir ?? join(getCwd(), \"logs\");\n this.ensureLogDirs();\n // Initialize EnvManager with watching enabled\n this.envManager = new EnvManager({\n cwd: config.cwd,\n files: config.envFiles,\n watch: true,\n });\n\n // Register env change handler\n this.envChangeUnsubscribe = this.envManager.onChange((changedKeys) => {\n this.handleEnvChange(changedKeys);\n });\n\n // Automatically register shutdown handlers\n this.registerShutdownHandlers();\n }\n\n /**\n * Merge global env with process-specific env and apply cwd inheritance\n * Merge order: .env (global), config.env (global), .env.<processName>, processEnvFile, definition.env\n */\n private applyDefaults(\n processName: string,\n definition: ProcessDefinition,\n envFile?: string,\n ): ProcessDefinition {\n // Start with env from .env file (global)\n const envFromFiles = this.envManager.getEnvVars(processName);\n\n // Build the env file map for this specific process if envFile is provided\n let envFromCustomFile: Record<string, string> = {};\n if (envFile) {\n let key = this.envFileKeyByProcess.get(processName);\n if (!key) {\n key = `custom:${processName}`;\n this.envFileKeyByProcess.set(processName, key);\n this.envManager.registerFile(key, envFile);\n }\n envFromCustomFile = this.envManager.getEnvForKey(key);\n }\n\n return {\n ...definition,\n cwd: definition.cwd ?? this.config.cwd,\n env: {\n ...envFromFiles, // .env (global) + .env.<processName>\n ...this.config.env, // Global env from config\n ...envFromCustomFile, // Custom env file if specified\n ...definition.env, // Process-specific env overrides\n },\n };\n }\n\n private processLogFile(name: string): string {\n return join(this.logDir, \"process\", `${name}.log`);\n }\n\n private taskLogFile(name: string): string {\n return join(this.logDir, \"tasks\", `${name}.log`);\n }\n\n private cronLogFile(name: string): string {\n return join(this.logDir, \"cron\", `${name}.log`);\n }\n\n /**\n * Kill any process running on the configured port for a process\n */\n private async killPortForProcess(processName: string): Promise<void> {\n const port = this.processPortConfig.get(processName);\n if (port === undefined) return;\n\n const killed = await killProcessOnPort(port);\n if (killed) {\n this.logger.info(`Killed process on port ${port} before starting \"${processName}\"`);\n }\n }\n\n private ensureLogDirs(): void {\n mkdirSync(this.logDir, { recursive: true });\n mkdirSync(join(this.logDir, \"process\"), { recursive: true });\n mkdirSync(join(this.logDir, \"tasks\"), { recursive: true });\n mkdirSync(join(this.logDir, \"cron\"), { recursive: true });\n }\n\n /**\n * Handle env file changes\n */\n private handleEnvChange(changedKeys: string[]): void {\n if (this._state !== \"running\") {\n return; // Only handle changes when manager is running\n }\n\n this.logger.info(`Env files changed for keys: ${changedKeys.join(\", \")}`);\n\n // Check which processes are affected\n const affectedProcesses = new Set<string>();\n\n for (const key of changedKeys) {\n // Global key affects all processes\n if (key === \"global\") {\n for (const processName of this.restartingProcesses.keys()) {\n affectedProcesses.add(processName);\n }\n } else {\n // Specific key affects matching process\n if (this.restartingProcesses.has(key)) {\n affectedProcesses.add(key);\n }\n\n for (const [processName, customKey] of this.envFileKeyByProcess.entries()) {\n if (customKey === key && this.restartingProcesses.has(processName)) {\n affectedProcesses.add(processName);\n }\n }\n }\n }\n\n // Schedule restarts for affected processes\n for (const processName of affectedProcesses) {\n const reloadDelay = this.processEnvReloadConfig.get(processName);\n\n // Skip if reload is disabled for this process\n if (reloadDelay === false) {\n continue;\n }\n\n this.scheduleProcessReload(processName, reloadDelay);\n }\n }\n\n /**\n * Schedule a process reload with debouncing\n */\n private scheduleProcessReload(processName: string, reloadDelay?: EnvReloadDelay): void {\n // Clear existing timer if any\n const existingTimer = this.envReloadTimers.get(processName);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Determine delay in ms\n let delayMs: number;\n if (reloadDelay === false) {\n return; // Should not happen, but guard anyway\n } else if (reloadDelay === true || reloadDelay === \"immediately\") {\n delayMs = 0;\n } else if (typeof reloadDelay === \"number\") {\n delayMs = reloadDelay;\n } else {\n delayMs = 5000; // Default 5 seconds\n }\n\n this.logger.info(`Scheduling reload for process \"${processName}\" in ${delayMs}ms`);\n\n const timer = setTimeout(async () => {\n await this.reloadProcessEnv(processName);\n this.envReloadTimers.delete(processName);\n }, delayMs);\n\n this.envReloadTimers.set(processName, timer);\n }\n\n /**\n * Reload a process with updated env vars\n */\n private async reloadProcessEnv(processName: string): Promise<void> {\n const proc = this.restartingProcesses.get(processName);\n if (!proc) {\n this.logger.warn(`Process \"${processName}\" not found for env reload`);\n return;\n }\n\n this.logger.info(`Reloading process \"${processName}\" due to env change`);\n\n // Get the original config for this process\n const processConfig = this.config.processes?.find((p) => p.name === processName);\n if (!processConfig) {\n this.logger.warn(`Process config for \"${processName}\" not found`);\n return;\n }\n\n // Rebuild definition with updated env\n const updatedDefinition = this.applyDefaults(\n processName,\n processConfig.definition,\n processConfig.envFile,\n );\n\n // Reload the process (graceful restart)\n await proc.reload(updatedDefinition, true);\n }\n\n get state(): ManagerState {\n return this._state;\n }\n\n /**\n * Get all cron processes (read-only access)\n */\n getCronProcesses(): ReadonlyMap<string, CronProcess> {\n return this.cronProcesses;\n }\n\n /**\n * Get a specific cron process by name\n */\n getCronProcess(name: string): CronProcess | undefined {\n return this.cronProcesses.get(name);\n }\n\n /**\n * Get all restarting processes (read-only access)\n */\n getRestartingProcesses(): ReadonlyMap<string, RestartingProcess> {\n return this.restartingProcesses;\n }\n\n /**\n * Get a specific restarting process by name\n */\n getRestartingProcess(name: string): RestartingProcess | undefined {\n return this.restartingProcesses.get(name);\n }\n\n /**\n * Get the task list (read-only access)\n */\n getTaskList(): TaskList | null {\n return this.taskList;\n }\n\n /**\n * Get a restarting process by name or index\n */\n getProcessByTarget(target: string | number): RestartingProcess | undefined {\n if (typeof target === \"string\") {\n return this.restartingProcesses.get(target);\n }\n const entries = Array.from(this.restartingProcesses.values());\n return entries[target];\n }\n\n /**\n * Get a cron process by name or index\n */\n getCronByTarget(target: string | number): CronProcess | undefined {\n if (typeof target === \"string\") {\n return this.cronProcesses.get(target);\n }\n const entries = Array.from(this.cronProcesses.values());\n return entries[target];\n }\n\n /**\n * Get a task by id or index\n */\n getTaskByTarget(\n target: string | number,\n ): { id: string; state: string; processNames: string[] } | undefined {\n if (!this.taskList) return undefined;\n const tasks = this.taskList.tasks;\n\n if (typeof target === \"string\") {\n const task = tasks.find((t) => t.id === target);\n if (!task) return undefined;\n return {\n id: task.id,\n state: task.state,\n processNames: task.processes.map((p) => p.name),\n };\n }\n\n const task = tasks[target];\n if (!task) return undefined;\n return {\n id: task.id,\n state: task.state,\n processNames: task.processes.map((p) => p.name),\n };\n }\n\n /**\n * Start a restarting process by target\n */\n async startProcessByTarget(target: string | number): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n // Kill any process on the configured port before starting\n await this.killPortForProcess(proc.name);\n proc.start();\n return proc;\n }\n\n /**\n * Stop a restarting process by target\n */\n async stopProcessByTarget(target: string | number, timeout?: number): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n await proc.stop(timeout);\n return proc;\n }\n\n /**\n * Restart a restarting process by target\n */\n async restartProcessByTarget(\n target: string | number,\n force: boolean = false,\n ): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n // Kill any process on the configured port before restarting\n await this.killPortForProcess(proc.name);\n await proc.restart(force);\n return proc;\n }\n\n /**\n * Reload a restarting process with new definition\n */\n async reloadProcessByTarget(\n target: string | number,\n newDefinition: ProcessDefinition,\n options?: {\n restartImmediately?: boolean;\n updateOptions?: Partial<RestartingProcessOptions>;\n },\n ): Promise<RestartingProcess> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n\n // Apply global defaults to new definition\n const definitionWithDefaults = this.applyDefaults(proc.name, newDefinition);\n\n // Update options if provided\n if (options?.updateOptions) {\n proc.updateOptions(options.updateOptions);\n }\n\n // Reload with new definition\n await proc.reload(definitionWithDefaults, options?.restartImmediately ?? true);\n this.logger.info(`Reloaded process: ${proc.name}`);\n return proc;\n }\n\n /**\n * Remove a restarting process by target\n */\n async removeProcessByTarget(target: string | number, timeout?: number): Promise<void> {\n const proc = this.getProcessByTarget(target);\n if (!proc) {\n throw new Error(`Process not found: ${target}`);\n }\n\n // Stop the process first\n await proc.stop(timeout);\n\n // Remove from the map\n this.restartingProcesses.delete(proc.name);\n this.logger.info(`Removed process: ${proc.name}`);\n }\n\n /**\n * Add a task to the task list\n * Creates the task list if it doesn't exist and starts it\n */\n addTask(\n name: string,\n definition: ProcessDefinition,\n ): { id: string; state: string; processNames: string[] } {\n if (!this.taskList) {\n const taskListLogger = this.logger.child(\"tasks\", {\n logFile: this.taskLogFile(\"tasks\"),\n });\n this.taskList = new TaskList(\"runtime\", taskListLogger, undefined, (processName) => {\n return this.taskLogFile(processName);\n });\n }\n\n const namedProcess: NamedProcessDefinition = {\n name,\n process: this.applyDefaults(name, definition),\n };\n const id = this.taskList.addTask(namedProcess);\n\n // Start the task list if it's idle so the task runs immediately\n if (this.taskList.state === \"idle\") {\n this.taskList.start();\n }\n\n return {\n id,\n state: \"pending\",\n processNames: [name],\n };\n }\n\n removeTaskByTarget(target: string | number): {\n id: string;\n state: string;\n processNames: string[];\n } {\n if (!this.taskList) {\n throw new Error(`Task list not initialized`);\n }\n\n const removed = this.taskList.removeTaskByTarget(target);\n return {\n id: removed.id,\n state: removed.state,\n processNames: removed.processes.map((p) => p.name),\n };\n }\n\n /**\n * Add a restarting process at runtime\n */\n async addProcess(\n name: string,\n definition: ProcessDefinition,\n options?: RestartingProcessOptions,\n envReloadDelay?: EnvReloadDelay,\n port?: number,\n ): Promise<RestartingProcess> {\n if (this.restartingProcesses.has(name)) {\n throw new Error(`Process \"${name}\" already exists`);\n }\n\n const processLogger = this.logger.child(name, { logFile: this.processLogFile(name) });\n const restartingProcess = new RestartingProcess(\n name,\n this.applyDefaults(name, definition),\n options ?? DEFAULT_RESTART_OPTIONS,\n processLogger,\n );\n this.restartingProcesses.set(name, restartingProcess);\n\n // Track port config and kill any process on that port before starting\n if (port !== undefined) {\n this.processPortConfig.set(name, port);\n await this.killPortForProcess(name);\n }\n\n restartingProcess.start();\n\n // Track env reload config for this process\n this.processEnvReloadConfig.set(name, envReloadDelay ?? 5000);\n\n this.logger.info(`Added and started restarting process: ${name}`);\n return restartingProcess;\n }\n\n /**\n * Trigger a cron process by target\n */\n async triggerCronByTarget(target: string | number): Promise<CronProcess> {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n await cron.trigger();\n return cron;\n }\n\n /**\n * Start a cron process by target\n */\n startCronByTarget(target: string | number): CronProcess {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n cron.start();\n return cron;\n }\n\n /**\n * Stop a cron process by target\n */\n async stopCronByTarget(target: string | number, timeout?: number): Promise<CronProcess> {\n const cron = this.getCronByTarget(target);\n if (!cron) {\n throw new Error(`Cron not found: ${target}`);\n }\n await cron.stop(timeout);\n return cron;\n }\n\n /**\n * Start the manager:\n * 1. Run task list (if configured) and wait for completion\n * 2. Create and start all cron/restarting processes\n */\n async start(): Promise<void> {\n if (this._state !== \"idle\" && this._state !== \"stopped\") {\n throw new Error(`Manager is already ${this._state}`);\n }\n\n this.logger.info(`Starting manager`);\n\n // Phase 1: Run initialization tasks\n if (this.config.tasks && this.config.tasks.length > 0) {\n this._state = \"initializing\";\n this.logger.info(`Running initialization tasks`);\n\n const taskListLogger = this.logger.child(\"tasks\");\n // Apply defaults to all tasks\n const tasksWithDefaults = this.config.tasks.map((task) => ({\n name: task.name,\n process: this.applyDefaults(task.name, task.definition, task.envFile),\n }));\n this.taskList = new TaskList(\"init\", taskListLogger, tasksWithDefaults, (processName) => {\n return this.taskLogFile(processName);\n });\n\n this.taskList.start();\n await this.taskList.waitUntilIdle();\n\n // Check if any tasks failed\n const failedTasks = this.taskList.tasks.filter((t) => t.state === \"failed\");\n if (failedTasks.length > 0) {\n this._state = \"stopped\";\n const failedNames = failedTasks.map((t) => t.id).join(\", \");\n throw new Error(`Initialization failed: tasks [${failedNames}] failed`);\n }\n\n this.logger.info(`Initialization tasks completed`);\n }\n\n // Phase 2: Create and start cron processes\n if (this.config.crons) {\n for (const entry of this.config.crons) {\n const processLogger = this.logger.child(entry.name, {\n logFile: this.cronLogFile(entry.name),\n });\n const cronProcess = new CronProcess(\n entry.name,\n this.applyDefaults(entry.name, entry.definition, entry.envFile),\n entry.options,\n processLogger,\n );\n this.cronProcesses.set(entry.name, cronProcess);\n cronProcess.start();\n this.logger.info(`Started cron process: ${entry.name}`);\n }\n }\n\n // Phase 3: Create and start restarting processes\n if (this.config.processes) {\n for (const entry of this.config.processes) {\n const processLogger = this.logger.child(entry.name, {\n logFile: this.processLogFile(entry.name),\n });\n const restartingProcess = new RestartingProcess(\n entry.name,\n this.applyDefaults(entry.name, entry.definition, entry.envFile),\n entry.options ?? DEFAULT_RESTART_OPTIONS,\n processLogger,\n );\n this.restartingProcesses.set(entry.name, restartingProcess);\n\n // Track port config and kill any process on that port before starting\n if (entry.port !== undefined) {\n this.processPortConfig.set(entry.name, entry.port);\n await this.killPortForProcess(entry.name);\n }\n\n restartingProcess.start();\n\n // Track env reload config for this process\n this.processEnvReloadConfig.set(\n entry.name,\n entry.envReloadDelay ?? 5000, // Default to 5000ms\n );\n\n this.logger.info(`Started restarting process: ${entry.name}`);\n }\n }\n\n this._state = \"running\";\n this.logger.info(\n `Manager started with ${this.cronProcesses.size} cron process(es) and ${this.restartingProcesses.size} restarting process(es)`,\n );\n }\n\n /**\n * Stop all managed processes\n */\n async stop(timeout?: number): Promise<void> {\n if (this._state === \"idle\" || this._state === \"stopped\") {\n this._state = \"stopped\";\n this.unregisterShutdownHandlers();\n return;\n }\n\n this._state = \"stopping\";\n this.logger.info(`Stopping manager`);\n\n // Clear all env reload timers\n for (const timer of this.envReloadTimers.values()) {\n clearTimeout(timer);\n }\n this.envReloadTimers.clear();\n\n // Unsubscribe from env changes\n if (this.envChangeUnsubscribe) {\n this.envChangeUnsubscribe();\n this.envChangeUnsubscribe = null;\n }\n\n // Dispose env manager\n this.envManager.dispose();\n\n // Stop task list if still running\n if (this.taskList) {\n await this.taskList.stop(timeout);\n }\n\n // Stop all cron processes in parallel\n const cronStopPromises = Array.from(this.cronProcesses.values()).map((p) => p.stop(timeout));\n\n // Stop all restarting processes in parallel\n const restartingStopPromises = Array.from(this.restartingProcesses.values()).map((p) =>\n p.stop(timeout),\n );\n\n await Promise.all([...cronStopPromises, ...restartingStopPromises]);\n\n this._state = \"stopped\";\n this.logger.info(`Manager stopped`);\n\n this.unregisterShutdownHandlers();\n }\n\n /**\n * Register signal handlers for graceful shutdown\n * Called automatically by constructor\n */\n private registerShutdownHandlers(): void {\n if (this.signalHandlers.size > 0) {\n this.logger.warn(`Shutdown handlers already registered`);\n return;\n }\n\n for (const signal of SHUTDOWN_SIGNALS) {\n const handler = () => this.handleSignal(signal);\n this.signalHandlers.set(signal, handler);\n process.on(signal, handler);\n this.logger.debug(`Registered handler for ${signal}`);\n }\n\n this.logger.info(`Shutdown handlers registered for signals: ${SHUTDOWN_SIGNALS.join(\", \")}`);\n }\n\n /**\n * Unregister signal handlers for graceful shutdown\n */\n private unregisterShutdownHandlers(): void {\n if (this.signalHandlers.size === 0) {\n return;\n }\n\n for (const [signal, handler] of this.signalHandlers.entries()) {\n process.off(signal, handler);\n this.logger.debug(`Unregistered handler for ${signal}`);\n }\n\n this.signalHandlers.clear();\n }\n\n /**\n * Wait for shutdown to complete (useful for keeping process alive)\n * Resolves when the manager has fully stopped\n */\n async waitForShutdown(): Promise<void> {\n // If already stopped, return immediately\n if (this._state === \"stopped\") {\n return;\n }\n\n // If shutdown is in progress, wait for it\n if (this.shutdownPromise) {\n await this.shutdownPromise;\n return;\n }\n\n // Wait for state to become stopped\n return new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (this._state === \"stopped\") {\n clearInterval(checkInterval);\n resolve();\n }\n }, 100);\n });\n }\n\n /**\n * Trigger graceful shutdown programmatically\n */\n async shutdown(): Promise<void> {\n if (this.isShuttingDown) {\n this.logger.warn(`Shutdown already in progress`);\n if (this.shutdownPromise) {\n await this.shutdownPromise;\n }\n return;\n }\n\n this.isShuttingDown = true;\n this.logger.info(`Initiating graceful shutdown (timeout: ${SHUTDOWN_TIMEOUT_MS}ms)`);\n\n this.shutdownPromise = this.performShutdown();\n await this.shutdownPromise;\n }\n\n private handleSignal(signal: NodeJS.Signals): void {\n this.logger.info(`Received ${signal}, initiating graceful shutdown...`);\n\n // Prevent handling multiple signals\n if (this.isShuttingDown) {\n this.logger.warn(`Shutdown already in progress, ignoring ${signal}`);\n return;\n }\n\n this.isShuttingDown = true;\n this.shutdownPromise = this.performShutdown();\n\n this.shutdownPromise\n .then(() => {\n this.logger.info(`Exiting with code ${SHUTDOWN_EXIT_CODE}`);\n process.exit(SHUTDOWN_EXIT_CODE);\n })\n .catch((err) => {\n this.logger.error(`Shutdown error:`, err);\n process.exit(1);\n });\n }\n\n private async performShutdown(): Promise<void> {\n // Create a timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Shutdown timed out after ${SHUTDOWN_TIMEOUT_MS}ms`));\n }, SHUTDOWN_TIMEOUT_MS);\n });\n\n try {\n // Race between graceful stop and timeout\n await Promise.race([this.stop(SHUTDOWN_TIMEOUT_MS), timeoutPromise]);\n this.logger.info(`Graceful shutdown completed`);\n } catch (err) {\n this.logger.error(`Shutdown error:`, err);\n // Force stop on timeout\n this._state = \"stopped\";\n throw err;\n } finally {\n this.isShuttingDown = false;\n this.shutdownPromise = null;\n }\n }\n}\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { createServer } from \"node:http\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport * as v from \"valibot\";\nimport { router } from \"./api/server.ts\";\nimport { Manager, ManagerConfigSchema } from \"./manager.ts\";\nimport { logger } from \"./logger.ts\";\nimport { tsImport } from \"tsx/esm/api\";\nimport Table from \"cli-table3\";\nimport { createClient } from \"./api/client.ts\";\nimport { ProcessDefinitionSchema } from \"./api/contract.ts\";\n\nconst program = new Command();\n\nprogram\n .name(\"pidnap\")\n .description(\"Process manager with init system capabilities\")\n .version(\"0.0.0-dev.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize and run the process manager with config file\")\n .option(\"-c, --config <path>\", \"Path to config file\", \"pidnap.config.ts\")\n .action(async (options) => {\n const initLogger = logger({ name: \"pidnap\" });\n try {\n // Resolve config file path\n const configPath = resolve(process.cwd(), options.config);\n const configUrl = pathToFileURL(configPath).href;\n\n // Import the config file\n const configModule = await tsImport(configUrl, { parentURL: import.meta.url });\n const rawConfig =\n configModule.default.default || configModule.default || configModule.config || {};\n\n // Parse and validate the config with Valibot\n const config = v.parse(ManagerConfigSchema, rawConfig);\n\n // Extract HTTP config with defaults\n const host = config.http?.host ?? \"localhost\";\n const port = config.http?.port ?? 3000;\n const authToken = config.http?.authToken;\n\n // Create manager with config\n const logDir = config.logDir ?? resolve(process.cwd(), \"logs\");\n const managerLogger = logger({ name: \"pidnap\", logFile: resolve(logDir, \"pidnap.log\") });\n const manager = new Manager(config, managerLogger);\n\n // Setup ORPC server with optional auth token middleware\n const handler = new RPCHandler(router, {\n interceptors: [\n onError((error) => {\n managerLogger.error(error);\n }),\n ],\n });\n\n const server = createServer(async (req, res) => {\n // Check auth token if configured\n if (authToken) {\n const providedToken = req.headers[\"authorization\"]?.replace(\"Bearer \", \"\");\n if (providedToken !== authToken) {\n res.statusCode = 401;\n res.end(\"Unauthorized\");\n return;\n }\n }\n\n const { matched } = await handler.handle(req, res, {\n prefix: \"/rpc\",\n context: { manager },\n });\n if (matched) return;\n res.statusCode = 404;\n res.end(\"Not found\");\n });\n\n server.listen(port, host, async () => {\n managerLogger.info(`pidnap RPC server running on http://${host}:${port}`);\n if (authToken) {\n managerLogger.info(\"Auth token required for API access\");\n }\n\n try {\n await manager.start();\n } catch (err) {\n managerLogger.error(\"Failed to start manager:\", err);\n server.close();\n process.exit(1);\n }\n });\n\n // Wait for shutdown\n await manager.waitForShutdown();\n\n // Close server on shutdown\n server.close();\n } catch (error) {\n initLogger.error(\"Failed to start pidnap:\", error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"status\")\n .description(\"Show manager status\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const status = await client.manager.status();\n\n const table = new Table({ head: [\"State\", \"Processes\", \"Crons\", \"Tasks\"] });\n table.push([status.state, status.processCount, status.cronCount, status.taskCount]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to fetch status:\", error);\n process.exit(1);\n }\n });\n\nconst processes = program.command(\"processes\").description(\"Manage restarting processes\");\n\nprocesses\n .command(\"list\")\n .description(\"List restarting processes\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const processes = await client.processes.list();\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n for (const proc of processes) {\n table.push([proc.name, proc.state, proc.restarts]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list processes:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"get\")\n .description(\"Get a restarting process by name or index\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"add\")\n .description(\"Add a restarting process\")\n .requiredOption(\"-n, --name <name>\", \"Process name\")\n .requiredOption(\"-d, --definition <json>\", \"Process definition JSON\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const definition = parseDefinition(options.definition);\n const proc = await client.processes.add({ name: options.name, definition });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to add process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"start\")\n .description(\"Start a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.start({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to start process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"stop\")\n .description(\"Stop a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.stop({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to stop process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"restart\")\n .description(\"Restart a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-f, --force\", \"Force restart\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const proc = await client.processes.restart({\n target: parseTarget(target),\n force: options.force,\n });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Restarts\"] });\n table.push([proc.name, proc.state, proc.restarts]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to restart process:\", error);\n process.exit(1);\n }\n });\n\nprocesses\n .command(\"remove\")\n .description(\"Remove a restarting process\")\n .argument(\"<target>\", \"Process name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n await client.processes.remove({ target: parseTarget(target) });\n console.log(\"Process removed\");\n } catch (error) {\n console.error(\"Failed to remove process:\", error);\n process.exit(1);\n }\n });\n\nconst crons = program.command(\"crons\").description(\"Manage cron processes\");\n\ncrons\n .command(\"list\")\n .description(\"List cron processes\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const crons = await client.crons.list();\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n for (const cron of crons) {\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list crons:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"get\")\n .description(\"Get a cron process by name or index\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"trigger\")\n .description(\"Trigger a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.trigger({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to trigger cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"start\")\n .description(\"Start a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.start({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to start cron:\", error);\n process.exit(1);\n }\n });\n\ncrons\n .command(\"stop\")\n .description(\"Stop a cron process\")\n .argument(\"<target>\", \"Cron name or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const cron = await client.crons.stop({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Name\", \"State\", \"Runs\", \"Fails\", \"Next Run\"] });\n table.push([cron.name, cron.state, cron.runCount, cron.failCount, cron.nextRun ?? \"-\"]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to stop cron:\", error);\n process.exit(1);\n }\n });\n\nconst tasks = program.command(\"tasks\").description(\"Manage tasks\");\n\ntasks\n .command(\"list\")\n .description(\"List tasks\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const tasks = await client.tasks.list();\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n for (const task of tasks) {\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n }\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to list tasks:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"get\")\n .description(\"Get a task by id or index\")\n .argument(\"<target>\", \"Task id or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const task = await client.tasks.get({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to get task:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"add\")\n .description(\"Add a task\")\n .requiredOption(\"-n, --name <name>\", \"Task name\")\n .requiredOption(\"-d, --definition <json>\", \"Process definition JSON\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (options) => {\n try {\n const client = createClient(options.url);\n const definition = parseDefinition(options.definition);\n const task = await client.tasks.add({ name: options.name, definition });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to add task:\", error);\n process.exit(1);\n }\n });\n\ntasks\n .command(\"remove\")\n .description(\"Remove a task by id or index\")\n .argument(\"<target>\", \"Task id or index\")\n .option(\"-u, --url <url>\", \"RPC server URL\", \"http://localhost:3000/rpc\")\n .action(async (target, options) => {\n try {\n const client = createClient(options.url);\n const task = await client.tasks.remove({ target: parseTarget(target) });\n\n const table = new Table({ head: [\"Id\", \"State\", \"Processes\"] });\n table.push([task.id, task.state, task.processNames.join(\", \")]);\n console.log(table.toString());\n } catch (error) {\n console.error(\"Failed to remove task:\", error);\n process.exit(1);\n }\n });\n\nconst TargetSchema = v.union([v.string(), v.number()]);\ntype ProcessDefinition = v.InferOutput<typeof ProcessDefinitionSchema>;\n\nfunction parseTarget(value: string): string | number {\n const asNumber = Number(value);\n return v.parse(TargetSchema, Number.isNaN(asNumber) ? value : asNumber);\n}\n\nfunction parseDefinition(raw: string): ProcessDefinition {\n try {\n const parsed = JSON.parse(raw);\n return v.parse(ProcessDefinitionSchema, parsed);\n } catch (error) {\n console.error(\"Invalid --definition JSON. Expected a ProcessDefinition.\");\n throw error;\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -69,6 +69,7 @@ declare const ManagerConfigSchema: v.ObjectSchema<{
|
|
|
69
69
|
}, undefined>, undefined>;
|
|
70
70
|
readonly envFile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
71
71
|
readonly envReloadDelay: v.OptionalSchema<v.UnionSchema<[v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.LiteralSchema<"immediately", undefined>], undefined>, undefined>;
|
|
72
|
+
readonly port: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
72
73
|
}, undefined>, undefined>, undefined>;
|
|
73
74
|
}, undefined>;
|
|
74
75
|
type ManagerConfig = v.InferOutput<typeof ManagerConfigSchema>;
|
|
@@ -145,6 +146,15 @@ declare class EnvManager {
|
|
|
145
146
|
getAllEnv(): ReadonlyMap<string, Record<string, string>>;
|
|
146
147
|
}
|
|
147
148
|
//#endregion
|
|
149
|
+
//#region src/tree-kill.d.ts
|
|
150
|
+
/**
|
|
151
|
+
* Kill a process and all its descendants (children, grandchildren, etc.)
|
|
152
|
+
* @param pid - The process ID to kill
|
|
153
|
+
* @param signal - The signal to send (default: SIGTERM)
|
|
154
|
+
* @returns Promise that resolves when all processes have been signaled
|
|
155
|
+
*/
|
|
156
|
+
declare function treeKill(pid: number, signal?: NodeJS.Signals): Promise<void>;
|
|
157
|
+
//#endregion
|
|
148
158
|
//#region src/index.d.ts
|
|
149
159
|
declare function defineConfig(config: ManagerConfig): {
|
|
150
160
|
http?: {
|
|
@@ -223,8 +233,9 @@ declare function defineConfig(config: ManagerConfig): {
|
|
|
223
233
|
} | undefined;
|
|
224
234
|
envFile?: string | undefined;
|
|
225
235
|
envReloadDelay?: number | boolean | "immediately" | undefined;
|
|
236
|
+
port?: number | undefined;
|
|
226
237
|
}[] | undefined;
|
|
227
238
|
};
|
|
228
239
|
//#endregion
|
|
229
|
-
export { BackoffStrategy, BackoffStrategySchema, CrashLoopConfig, CrashLoopConfigSchema, CronProcess, CronProcessOptions, CronProcessOptionsSchema, CronProcessState, CronProcessStateSchema, EnvChangeCallback, EnvManager, EnvManagerConfig, LazyProcess, Logger, NamedProcessDefinition, NamedProcessDefinitionSchema, ProcessDefinition, ProcessDefinitionSchema, ProcessState, ProcessStateSchema, RestartPolicy, RestartPolicySchema, RestartingProcess, RestartingProcessOptions, RestartingProcessOptionsSchema, RestartingProcessState, RestartingProcessStateSchema, RetryConfig, RetryConfigSchema, TaskEntry, TaskList, TaskListState, TaskState, TaskStateSchema, defineConfig, logger };
|
|
240
|
+
export { BackoffStrategy, BackoffStrategySchema, CrashLoopConfig, CrashLoopConfigSchema, CronProcess, CronProcessOptions, CronProcessOptionsSchema, CronProcessState, CronProcessStateSchema, EnvChangeCallback, EnvManager, EnvManagerConfig, LazyProcess, Logger, NamedProcessDefinition, NamedProcessDefinitionSchema, ProcessDefinition, ProcessDefinitionSchema, ProcessState, ProcessStateSchema, RestartPolicy, RestartPolicySchema, RestartingProcess, RestartingProcessOptions, RestartingProcessOptionsSchema, RestartingProcessState, RestartingProcessStateSchema, RetryConfig, RetryConfigSchema, TaskEntry, TaskList, TaskListState, TaskState, TaskStateSchema, defineConfig, logger, treeKill };
|
|
230
241
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/manager.ts","../src/env-manager.ts","../src/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/manager.ts","../src/env-manager.ts","../src/tree-kill.ts","../src/index.ts"],"mappings":";;;;cAgEa,mBAAA,EAAmB,CAAA,CAAA,YAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAWpB,aAAA,GAAgB,CAAA,CAAE,WAAA,QAAmB,mBAAA;;;KCtErC,iBAAA,IAAqB,WAAA;AAAA,UAEhB,gBAAA;;;ADyDjB;;ECpDE,GAAA;;;;;;EAOA,KAAA,GAAQ,MAAA;;;;;EAMR,KAAA;AAAA;AAAA,cAGW,UAAA;EAAA,QACH,GAAA;EAAA,QACA,GAAA;EAAA,QACA,YAAA;EAAA,QACA,QAAA;EAAA,QACA,UAAA;EAAA,QACA,eAAA;EAAA,QACA,oBAAA;cAEI,MAAA,GAAQ,gBAAA;EAepB,YAAA,CAAa,GAAA,UAAa,QAAA;EAI1B,YAAA,CAAa,GAAA,WAAc,MAAA;;;;UAOnB,mBAAA;;;;UA6BA,WAAA;;;;UA8BA,SAAA;;;;UAiBA,gBAAA;;;;UAmBA,UAAA;;;;;EA6BR,QAAA,CAAS,QAAA,EAAU,iBAAA;;;;EAUnB,OAAA,CAAA;;;;;;EAsBA,UAAA,CAAW,UAAA,YAAsB,MAAA;;;;EAcjC,SAAA,CAAA,GAAa,WAAA,SAAoB,MAAA;AAAA;;;;;;;ADzKnC;;iBEtDsB,QAAA,CAAS,GAAA,UAAa,MAAA,GAAQ,MAAA,CAAO,OAAA,GAAsB,OAAA;;;iBCRjE,YAAA,CAAa,MAAA,EAAQ,aAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as ProcessDefinitionSchema, a as TaskStateSchema, c as CronProcessStateSchema, d as CrashLoopConfigSchema, f as RestartPolicySchema, g as LazyProcess, h as RestartingProcessStateSchema, i as TaskList, l as RetryConfigSchema, m as RestartingProcessOptionsSchema, n as EnvManager, o as CronProcess, p as RestartingProcess, r as NamedProcessDefinitionSchema, s as CronProcessOptionsSchema, t as logger, u as BackoffStrategySchema, v as ProcessStateSchema } from "./logger-
|
|
1
|
+
import { _ as ProcessDefinitionSchema, a as TaskStateSchema, c as CronProcessStateSchema, d as CrashLoopConfigSchema, f as RestartPolicySchema, g as LazyProcess, h as RestartingProcessStateSchema, i as TaskList, l as RetryConfigSchema, m as RestartingProcessOptionsSchema, n as EnvManager, o as CronProcess, p as RestartingProcess, r as NamedProcessDefinitionSchema, s as CronProcessOptionsSchema, t as logger, u as BackoffStrategySchema, v as ProcessStateSchema, y as treeKill } from "./logger-uliALovz.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
function defineConfig(config) {
|
|
@@ -6,5 +6,5 @@ function defineConfig(config) {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
//#endregion
|
|
9
|
-
export { BackoffStrategySchema, CrashLoopConfigSchema, CronProcess, CronProcessOptionsSchema, CronProcessStateSchema, EnvManager, LazyProcess, NamedProcessDefinitionSchema, ProcessDefinitionSchema, ProcessStateSchema, RestartPolicySchema, RestartingProcess, RestartingProcessOptionsSchema, RestartingProcessStateSchema, RetryConfigSchema, TaskList, TaskStateSchema, defineConfig, logger };
|
|
9
|
+
export { BackoffStrategySchema, CrashLoopConfigSchema, CronProcess, CronProcessOptionsSchema, CronProcessStateSchema, EnvManager, LazyProcess, NamedProcessDefinitionSchema, ProcessDefinitionSchema, ProcessStateSchema, RestartPolicySchema, RestartingProcess, RestartingProcessOptionsSchema, RestartingProcessStateSchema, RetryConfigSchema, TaskList, TaskStateSchema, defineConfig, logger, treeKill };
|
|
10
10
|
//# sourceMappingURL=index.mjs.map
|