omegon 0.6.16 → 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.
@@ -105,7 +105,11 @@ export const DEPS: Dep[] = [
105
105
  tier: "core",
106
106
  check: () => hasCmd("nix"),
107
107
  install: [
108
- { platform: "any", cmd: "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm" },
108
+ // --no-confirm: headless (stdin is closed)
109
+ // --init none: skip systemd/launchd service setup — required on immutable
110
+ // distros (Bazzite/Silverblue) where systemd-reload fails, and harmless
111
+ // elsewhere (nix daemon is started on demand).
112
+ { platform: "any", cmd: "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm --init none" },
109
113
  ],
110
114
  url: "https://zero-to-nix.com",
111
115
  },
@@ -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 */
@@ -1103,12 +1093,17 @@ async function installDeps(ctx: CommandContext, deps: DepStatus[]): Promise<void
1103
1093
  continue;
1104
1094
  }
1105
1095
 
1106
- ctx.ui.notify(`\n${step} 📦 Installing ${dep.name}…`);
1107
- ctx.ui.notify(` → \`${cmd}\``);
1096
+ ctx.ui.notify(`\n${step} 📦 Installing ${dep.name}…\n → \`${cmd}\``);
1108
1097
 
1098
+ // Collect output lines — show progress inline but also keep them
1099
+ // so we can dump a readable block on failure.
1100
+ const outputLines: string[] = [];
1109
1101
  const exitCode = await runAsync(
1110
1102
  cmd,
1111
- (line) => ctx.ui.notify(line),
1103
+ (line) => {
1104
+ outputLines.push(line);
1105
+ ctx.ui.notify(line);
1106
+ },
1112
1107
  );
1113
1108
 
1114
1109
  // Patch PATH immediately after installing bootstrapping deps so the rest
@@ -1124,13 +1119,22 @@ async function installDeps(ctx: CommandContext, deps: DepStatus[]): Promise<void
1124
1119
  ctx.ui.notify(`${step} ✅ ${dep.name} installed successfully`);
1125
1120
  } else if (exitCode === 124) {
1126
1121
  ctx.ui.notify(`${step} ❌ ${dep.name} install timed out (10 min limit)`);
1127
- } else if (exitCode === 0) {
1128
- ctx.ui.notify(`${step} ⚠️ Command succeeded but ${dep.name} not found on PATH — you may need to open a new shell.`);
1129
1122
  } else {
1130
- ctx.ui.notify(`${step} Failed to install ${dep.name} (exit ${exitCode})`);
1131
- const hints = dep.install.filter((o) => o.cmd !== cmd);
1132
- if (hints.length > 0) ctx.ui.notify(` Alternative: \`${hints[0]!.cmd}\``);
1133
- if (dep.url) ctx.ui.notify(` Manual install: ${dep.url}`);
1123
+ // Dump the last N lines of output so the operator can see what went wrong
1124
+ const tail = outputLines.slice(-20).join("\n");
1125
+ const status = exitCode === 0
1126
+ ? `Command succeeded but ${dep.name} not found on PATH`
1127
+ : `Failed to install ${dep.name} (exit ${exitCode})`;
1128
+ const block = [
1129
+ `${step} ❌ ${status}`,
1130
+ "",
1131
+ "Output (last 20 lines):",
1132
+ "```",
1133
+ tail,
1134
+ "```",
1135
+ ...(dep.url ? [`Manual install: ${dep.url}`] : []),
1136
+ ].join("\n");
1137
+ ctx.ui.notify(block);
1134
1138
  }
1135
1139
  }
1136
1140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omegon",
3
- "version": "0.6.16",
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",