@episoda/cli 0.2.166 → 0.2.167

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/index.js CHANGED
@@ -3003,7 +3003,17 @@ var status = {
3003
3003
  var fs = __toESM(require("fs"));
3004
3004
  var path = __toESM(require("path"));
3005
3005
  var import_child_process = require("child_process");
3006
+ var import_crypto = require("crypto");
3006
3007
  var import_core = __toESM(require_dist());
3008
+ function logSignalDispatch(input) {
3009
+ const payload = {
3010
+ correlationId: (0, import_crypto.randomUUID)(),
3011
+ ...input,
3012
+ actorPid: process.pid,
3013
+ at: (/* @__PURE__ */ new Date()).toISOString()
3014
+ };
3015
+ console.log(`[DaemonManager] SignalDispatch ${JSON.stringify(payload)}`);
3016
+ }
3007
3017
  function killAllEpisodaProcesses() {
3008
3018
  const currentPid = process.pid;
3009
3019
  let killedCount = 0;
@@ -3023,6 +3033,13 @@ function killAllEpisodaProcesses() {
3023
3033
  const pid = parseInt(parts[1], 10);
3024
3034
  if (isNaN(pid) || pid === currentPid) continue;
3025
3035
  try {
3036
+ logSignalDispatch({
3037
+ initiator: "killAllEpisodaProcesses",
3038
+ pid,
3039
+ signal: "SIGTERM",
3040
+ reason: "stale_process_cleanup",
3041
+ command: line.trim()
3042
+ });
3026
3043
  process.kill(pid, "SIGTERM");
3027
3044
  killedCount++;
3028
3045
  console.log(`[Cleanup] Killed stale process PID ${pid}`);
@@ -3140,6 +3157,12 @@ async function stopDaemon(timeout = 5e3) {
3140
3157
  return false;
3141
3158
  }
3142
3159
  try {
3160
+ logSignalDispatch({
3161
+ initiator: "stopDaemon",
3162
+ pid,
3163
+ signal: "SIGTERM",
3164
+ reason: "graceful_shutdown"
3165
+ });
3143
3166
  process.kill(pid, "SIGTERM");
3144
3167
  const startTime = Date.now();
3145
3168
  while (Date.now() - startTime < timeout) {
@@ -3155,6 +3178,12 @@ async function stopDaemon(timeout = 5e3) {
3155
3178
  }
3156
3179
  }
3157
3180
  console.warn(`Daemon didn't stop gracefully, forcing shutdown (PID: ${pid})`);
3181
+ logSignalDispatch({
3182
+ initiator: "stopDaemon",
3183
+ pid,
3184
+ signal: "SIGKILL",
3185
+ reason: `graceful_shutdown_timeout_${timeout}ms`
3186
+ });
3158
3187
  process.kill(pid, "SIGKILL");
3159
3188
  const pidPath = getPidFilePath();
3160
3189
  if (fs.existsSync(pidPath)) {
@@ -4525,6 +4554,7 @@ async function promptYesNo(question, defaultValue = true) {
4525
4554
 
4526
4555
  // src/commands/daemon.ts
4527
4556
  var CONNECTION_MAX_RETRIES = 3;
4557
+ var FOREGROUND_DAEMON_MONITOR_INTERVAL_MS = 5e3;
4528
4558
  async function maybeRegisterProtocolHandler() {
4529
4559
  if (process.env.EPISODA_PROTOCOL_INVOKE === "1") {
4530
4560
  return;
@@ -4724,6 +4754,13 @@ Received ${signal}. Daemon continues running in background.`);
4724
4754
  };
4725
4755
  process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
4726
4756
  process.on("SIGINT", () => shutdownHandler("SIGINT"));
4757
+ setInterval(() => {
4758
+ const activePid = isDaemonRunning();
4759
+ if (!activePid) {
4760
+ status.error("Daemon process exited unexpectedly; terminating foreground wrapper for supervisor restart.");
4761
+ process.exit(1);
4762
+ }
4763
+ }, FOREGROUND_DAEMON_MONITOR_INTERVAL_MS);
4727
4764
  setInterval(() => {
4728
4765
  }, 1e3 * 60 * 60);
4729
4766
  await new Promise(() => {