@episoda/cli 0.2.166 → 0.2.168

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)) {
@@ -4503,39 +4532,14 @@ shell.Run cmd, 0, False
4503
4532
  }
4504
4533
  }
4505
4534
 
4506
- // src/utils/prompt.ts
4507
- var readline = __toESM(require("readline"));
4508
- async function promptYesNo(question, defaultValue = true) {
4509
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
4510
- return defaultValue;
4511
- }
4512
- const rl = readline.createInterface({
4513
- input: process.stdin,
4514
- output: process.stdout
4515
- });
4516
- const suffix = defaultValue ? " [Y/n] " : " [y/N] ";
4517
- const answer = await new Promise((resolve5) => {
4518
- rl.question(`${question}${suffix}`, (response) => resolve5(response));
4519
- });
4520
- rl.close();
4521
- const normalized = answer.trim().toLowerCase();
4522
- if (!normalized) return defaultValue;
4523
- return normalized === "y" || normalized === "yes";
4524
- }
4525
-
4526
- // src/commands/daemon.ts
4527
- var CONNECTION_MAX_RETRIES = 3;
4528
- async function maybeRegisterProtocolHandler() {
4535
+ // src/commands/protocol-registration.ts
4536
+ async function ensureProtocolHandlerRegistered() {
4529
4537
  if (process.env.EPISODA_PROTOCOL_INVOKE === "1") {
4530
4538
  return;
4531
4539
  }
4532
4540
  if (isProtocolHandlerRegistered()) {
4533
4541
  return;
4534
4542
  }
4535
- const shouldRegister = await promptYesNo("Register episoda:// for one-click reconnects?");
4536
- if (!shouldRegister) {
4537
- return;
4538
- }
4539
4543
  const result = registerProtocolHandler();
4540
4544
  if (result.success) {
4541
4545
  status.success(result.message || "Protocol handler registered.");
@@ -4543,6 +4547,10 @@ async function maybeRegisterProtocolHandler() {
4543
4547
  status.warning(`Protocol handler not registered: ${result.error}`);
4544
4548
  }
4545
4549
  }
4550
+
4551
+ // src/commands/daemon.ts
4552
+ var CONNECTION_MAX_RETRIES = 3;
4553
+ var FOREGROUND_DAEMON_MONITOR_INTERVAL_MS = 5e3;
4546
4554
  function findGitRoot(startDir) {
4547
4555
  try {
4548
4556
  const result = (0, import_child_process5.execSync)("git rev-parse --show-toplevel", {
@@ -4706,7 +4714,7 @@ async function daemonCommand(options = {}) {
4706
4714
  } else {
4707
4715
  status.success("Connected to Episoda");
4708
4716
  }
4709
- await maybeRegisterProtocolHandler();
4717
+ await ensureProtocolHandlerRegistered();
4710
4718
  if (options.foreground) {
4711
4719
  status.info("");
4712
4720
  if (isCloudMode) {
@@ -4724,6 +4732,13 @@ Received ${signal}. Daemon continues running in background.`);
4724
4732
  };
4725
4733
  process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
4726
4734
  process.on("SIGINT", () => shutdownHandler("SIGINT"));
4735
+ setInterval(() => {
4736
+ const activePid = isDaemonRunning();
4737
+ if (!activePid) {
4738
+ status.error("Daemon process exited unexpectedly; terminating foreground wrapper for supervisor restart.");
4739
+ process.exit(1);
4740
+ }
4741
+ }, FOREGROUND_DAEMON_MONITOR_INTERVAL_MS);
4727
4742
  setInterval(() => {
4728
4743
  }, 1e3 * 60 * 60);
4729
4744
  await new Promise(() => {
@@ -7242,7 +7257,7 @@ function printExports(envVars) {
7242
7257
  // src/commands/env.ts
7243
7258
  var fs14 = __toESM(require("fs"));
7244
7259
  var path16 = __toESM(require("path"));
7245
- var readline2 = __toESM(require("readline"));
7260
+ var readline = __toESM(require("readline"));
7246
7261
  var import_core17 = __toESM(require_dist());
7247
7262
  async function envListCommand(options = {}) {
7248
7263
  const config = await (0, import_core17.loadConfig)();
@@ -7438,7 +7453,7 @@ async function envPullCommand(options = {}) {
7438
7453
  async function promptForValue(key) {
7439
7454
  if (!process.stdin.isTTY) {
7440
7455
  return new Promise((resolve5, reject) => {
7441
- const rl = readline2.createInterface({
7456
+ const rl = readline.createInterface({
7442
7457
  input: process.stdin,
7443
7458
  output: process.stdout
7444
7459
  });
@@ -7452,7 +7467,7 @@ async function promptForValue(key) {
7452
7467
  });
7453
7468
  }
7454
7469
  return new Promise((resolve5, reject) => {
7455
- const rl = readline2.createInterface({
7470
+ const rl = readline.createInterface({
7456
7471
  input: process.stdin,
7457
7472
  output: process.stdout
7458
7473
  });