omegon 0.6.17 → 0.6.18

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.
@@ -432,10 +432,9 @@ export default function (pi: ExtensionAPI) {
432
432
  /**
433
433
  * Replace the current Omegon process with a fresh instance.
434
434
  *
435
- * Resets terminal state (exits raw mode, alternate screen, mouse capture),
436
- * then uses shell `exec` to replace the process in-place. This avoids the
437
- * race between old-process TUI teardown and new-process TUI startup that
438
- * causes ANSI garbage when using detach+exit.
435
+ * Writes a tiny shell script that sleeps briefly (so this process can fully
436
+ * exit and release the terminal), then exec's the new Omegon. This avoids
437
+ * two TUI processes fighting over the same terminal simultaneously.
439
438
  */
440
439
  function restartOmegon(): never {
441
440
  const { command, argvPrefix } = resolveOmegonSubprocess();
@@ -454,38 +453,29 @@ function restartOmegon(): never {
454
453
  !a.startsWith("--no-extensions")
455
454
  );
456
455
 
457
- // Reset terminal to sane state before exec replaces us
458
- const reset = [
459
- "\x1b[?1049l", // exit alternate screen buffer
460
- "\x1b[?1000l", // disable mouse click tracking
461
- "\x1b[?1002l", // disable mouse drag tracking
462
- "\x1b[?1006l", // disable SGR mouse mode
463
- "\x1b[?25h", // show cursor
464
- "\x1b[0m", // reset attributes
465
- "\x1bc", // full terminal reset (RIS)
466
- ].join("");
467
- process.stdout.write(reset);
468
-
469
- // Exit raw mode if active
470
- if (process.stdin.isTTY && process.stdin.isRaw) {
471
- process.stdin.setRawMode(false);
472
- }
473
-
474
- // Build the exec command — shell `exec` replaces the process entirely,
475
- // no orphan child, no race between old and new TUI.
476
456
  const parts = [command, ...argvPrefix, ...userArgs].map(shellEscape);
477
- const child = spawn("sh", ["-c", `exec ${parts.join(" ")}`], {
457
+ const script = join(tmpdir(), `omegon-restart-${process.pid}.sh`);
458
+ writeFileSync(script, [
459
+ "#!/bin/sh",
460
+ // Wait for the old process to fully die and release the terminal
461
+ "sleep 0.3",
462
+ // Reset terminal to sane cooked state
463
+ "stty sane 2>/dev/null",
464
+ "printf '\\033c'",
465
+ // Replace this shell with new omegon
466
+ `exec ${parts.join(" ")}`,
467
+ ].join("\n") + "\n", { mode: 0o755 });
468
+
469
+ // Spawn the restart script detached — it will outlive us
470
+ const child = spawn("sh", [script], {
478
471
  stdio: "inherit",
472
+ detached: true,
479
473
  env: process.env,
480
474
  });
481
- // If exec fails for some reason, exit when the child does
482
- child.on("close", (code) => process.exit(code ?? 1));
483
- // Prevent Node from keeping the event loop alive for other reasons
484
475
  child.unref();
485
476
 
486
- // The sh -c exec should have replaced us. If we're still here,
487
- // just wait for the child.
488
- return undefined as never;
477
+ // Clean exit the script waits for us to die before starting new omegon
478
+ process.exit(0);
489
479
  }
490
480
 
491
481
  /** Escape a string for POSIX shell */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omegon",
3
- "version": "0.6.17",
3
+ "version": "0.6.18",
4
4
  "description": "Omegon — an opinionated distribution of pi (by Mario Zechner) with extensions for lifecycle management, memory, orchestration, and visualization",
5
5
  "bin": {
6
6
  "omegon": "bin/omegon.mjs",