@askexenow/exe-os 0.8.52 → 0.8.54

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/bin/cli.js CHANGED
@@ -12460,8 +12460,8 @@ ${info.componentStack ?? ""}
12460
12460
  }
12461
12461
  render() {
12462
12462
  if (this.state.error) {
12463
- return /* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
12464
- /* @__PURE__ */ jsxs(Box_default, { children: [
12463
+ return /* @__PURE__ */ jsxs(Box_default, { testID: "error-boundary", flexDirection: "column", paddingX: 1, paddingY: 1, children: [
12464
+ /* @__PURE__ */ jsxs(Box_default, { testID: "error-message", children: [
12465
12465
  /* @__PURE__ */ jsx2(Text, { backgroundColor: "red", color: "white", children: " ERROR " }),
12466
12466
  /* @__PURE__ */ jsxs(Text, { children: [
12467
12467
  " ",
@@ -12513,7 +12513,7 @@ function AlternateScreen({ children }) {
12513
12513
  process.stdout.write(SHOW_CURSOR + EXIT_ALT_SCREEN);
12514
12514
  };
12515
12515
  }, []);
12516
- return /* @__PURE__ */ jsx3(Box_default, { flexDirection: "column", height: rows, width: "100%", children });
12516
+ return /* @__PURE__ */ jsx3(Box_default, { testID: "alternate-screen", flexDirection: "column", height: rows, width: "100%", children });
12517
12517
  }
12518
12518
  var ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, CLEAR_AND_HOME, HIDE_CURSOR, SHOW_CURSOR;
12519
12519
  var init_AlternateScreen = __esm({
@@ -12579,6 +12579,7 @@ function Sidebar({
12579
12579
  return /* @__PURE__ */ jsxs2(
12580
12580
  Box_default,
12581
12581
  {
12582
+ testID: "sidebar-nav",
12582
12583
  flexDirection: "column",
12583
12584
  width: 26,
12584
12585
  borderStyle: "single",
@@ -12592,19 +12593,19 @@ function Sidebar({
12592
12593
  SECTIONS.map(({ key, label, shortcut }) => {
12593
12594
  const isActive = active === key;
12594
12595
  if (isActive && focused) {
12595
- return /* @__PURE__ */ jsxs2(Text, { backgroundColor: "#6B4C9A", color: "#F5D76E", bold: true, children: [
12596
+ return /* @__PURE__ */ jsx4(Box_default, { testID: `sidebar-item-${key}`, children: /* @__PURE__ */ jsxs2(Text, { backgroundColor: "#6B4C9A", color: "#F5D76E", bold: true, children: [
12596
12597
  "\u25B8 ",
12597
12598
  shortcut,
12598
12599
  " ",
12599
12600
  label
12600
- ] }, key);
12601
+ ] }) }, key);
12601
12602
  }
12602
- return /* @__PURE__ */ jsxs2(Text, { color: isActive ? "#F5D76E" : "#6B4C9A", children: [
12603
+ return /* @__PURE__ */ jsx4(Box_default, { testID: `sidebar-item-${key}`, children: /* @__PURE__ */ jsxs2(Text, { color: isActive ? "#F5D76E" : "#6B4C9A", children: [
12603
12604
  isActive ? "\u25B8 " : " ",
12604
12605
  shortcut,
12605
12606
  " ",
12606
12607
  label
12607
- ] }, key);
12608
+ ] }) }, key);
12608
12609
  })
12609
12610
  ] }),
12610
12611
  /* @__PURE__ */ jsx4(Text, { color: "#6B4C9A", children: " \u2715 Quit (q)" })
@@ -13049,9 +13050,9 @@ function Footer() {
13049
13050
  }
13050
13051
  });
13051
13052
  }
13052
- return /* @__PURE__ */ jsxs3(Box_default, { flexDirection: "column", children: [
13053
+ return /* @__PURE__ */ jsxs3(Box_default, { testID: "footer", flexDirection: "column", children: [
13053
13054
  /* @__PURE__ */ jsx5(Text, { color: "#3D3660", children: "\u2500".repeat(process.stdout.columns || 120) }),
13054
- /* @__PURE__ */ jsxs3(Box_default, { paddingX: 1, justifyContent: "space-between", children: [
13055
+ /* @__PURE__ */ jsxs3(Box_default, { testID: "footer-stats", paddingX: 1, justifyContent: "space-between", children: [
13055
13056
  /* @__PURE__ */ jsxs3(Box_default, { gap: 1, children: [
13056
13057
  currentSession ? /* @__PURE__ */ jsxs3(Fragment, { children: [
13057
13058
  /* @__PURE__ */ jsx5(Text, { color: "#22C55E", children: currentSession }),
@@ -13108,7 +13109,7 @@ import React16 from "react";
13108
13109
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
13109
13110
  function StatusDot({ status, showLabel = true }) {
13110
13111
  const { char, dotColor, label, labelColor } = STATUS_CONFIG[status];
13111
- return /* @__PURE__ */ jsxs4(Box_default, { gap: 0, children: [
13112
+ return /* @__PURE__ */ jsxs4(Box_default, { testID: "status-dot", gap: 0, children: [
13112
13113
  /* @__PURE__ */ jsx6(Text, { color: dotColor, children: char }),
13113
13114
  showLabel && /* @__PURE__ */ jsxs4(Text, { color: labelColor, children: [
13114
13115
  " ",
@@ -16201,8 +16202,8 @@ function CommandCenterView({
16201
16202
  setChatInput("");
16202
16203
  }, [sendMessage, isThinking]);
16203
16204
  if (chatMode) {
16204
- return /* @__PURE__ */ jsxs5(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16205
- /* @__PURE__ */ jsxs5(Box_default, { justifyContent: "space-between", alignItems: "center", children: [
16205
+ return /* @__PURE__ */ jsxs5(Box_default, { testID: "command-center-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16206
+ /* @__PURE__ */ jsxs5(Box_default, { testID: "command-center-header", justifyContent: "space-between", alignItems: "center", children: [
16206
16207
  /* @__PURE__ */ jsx7(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, children: /* @__PURE__ */ jsx7(Text, { bold: true, children: "Chat" }) }),
16207
16208
  /* @__PURE__ */ jsx7(Text, { color: "#6B4C9A", children: "Ctrl+L clear | Escape to return" })
16208
16209
  ] }),
@@ -16262,8 +16263,8 @@ function CommandCenterView({
16262
16263
  ] })
16263
16264
  ] });
16264
16265
  }
16265
- return /* @__PURE__ */ jsxs5(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16266
- /* @__PURE__ */ jsxs5(Box_default, { justifyContent: "space-between", alignItems: "center", children: [
16266
+ return /* @__PURE__ */ jsxs5(Box_default, { testID: "command-center-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16267
+ /* @__PURE__ */ jsxs5(Box_default, { testID: "command-center-header", justifyContent: "space-between", alignItems: "center", children: [
16267
16268
  /* @__PURE__ */ jsx7(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, children: /* @__PURE__ */ jsx7(Text, { bold: true, children: "Command Center" }) }),
16268
16269
  /* @__PURE__ */ jsx7(Text, { color: selectableProjects.some((p) => p.status === "active") ? "green" : "gray", children: selectableProjects.some((p) => p.status === "active") ? "\u25CF Active" : "\u25CF Idle" })
16269
16270
  ] }),
@@ -16332,7 +16333,7 @@ function CommandCenterView({
16332
16333
  );
16333
16334
  });
16334
16335
  sections.push(
16335
- /* @__PURE__ */ jsx7(Box_default, { flexDirection: "row", flexWrap: "wrap", gap: 1, children: cards }, `cards-${sectionKey++}`)
16336
+ /* @__PURE__ */ jsx7(Box_default, { testID: "command-center-cards", flexDirection: "row", flexWrap: "wrap", gap: 1, children: cards }, `cards-${sectionKey++}`)
16336
16337
  );
16337
16338
  currentProjects = [];
16338
16339
  };
@@ -16466,7 +16467,7 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
16466
16467
  });
16467
16468
  const modeLabel = demo ? "DEMO" : alive ? "INTERACTIVE" : "DISCONNECTED";
16468
16469
  const modeColor = demo ? "#6B4C9A" : alive ? "#22C55E" : "#6B7280";
16469
- return /* @__PURE__ */ jsxs6(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16470
+ return /* @__PURE__ */ jsxs6(Box_default, { testID: "tmux-pane", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
16470
16471
  /* @__PURE__ */ jsxs6(Box_default, { justifyContent: "space-between", children: [
16471
16472
  /* @__PURE__ */ jsxs6(Text, { bold: true, children: [
16472
16473
  employeeName,
@@ -19988,7 +19989,7 @@ function SessionsView({
19988
19989
  const inCarousel = carouselEmployees.length > 0;
19989
19990
  const prevName = inCarousel && carouselIdx > 0 ? carouselEmployees[carouselIdx - 1].name : null;
19990
19991
  const nextName = inCarousel && carouselIdx < carouselEmployees.length - 1 ? carouselEmployees[carouselIdx + 1].name : null;
19991
- return /* @__PURE__ */ jsxs7(Box_default, { flexDirection: "column", flexGrow: 1, children: [
19992
+ return /* @__PURE__ */ jsxs7(Box_default, { testID: "sessions-view", flexDirection: "column", flexGrow: 1, children: [
19992
19993
  inCarousel && /* @__PURE__ */ jsxs7(Box_default, { paddingX: 1, justifyContent: "space-between", children: [
19993
19994
  /* @__PURE__ */ jsxs7(Text, { children: [
19994
19995
  /* @__PURE__ */ jsx9(Text, { color: "#6B4C9A", children: prevName ? `\u25C4 ${prevName}` : "\u25C4 back" }),
@@ -20030,7 +20031,7 @@ function SessionsView({
20030
20031
  ] });
20031
20032
  }
20032
20033
  const flatItems = buildFlatList();
20033
- return /* @__PURE__ */ jsxs7(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20034
+ return /* @__PURE__ */ jsxs7(Box_default, { testID: "sessions-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20034
20035
  /* @__PURE__ */ jsx9(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx9(Text, { bold: true, children: "Sessions" }) }),
20035
20036
  /* @__PURE__ */ jsx9(Text, { color: "#6B4C9A", children: "Arrows to navigate, Enter to view/launch, k to kill, Escape to detach" }),
20036
20037
  !demo && !orch.isLoading && /* @__PURE__ */ jsxs7(Box_default, { gap: 2, marginTop: 0, children: [
@@ -20280,7 +20281,7 @@ function TasksView({ onBack }) {
20280
20281
  }
20281
20282
  const selected = taskRows[selectedTask]?.task;
20282
20283
  if (showDetail && selected) {
20283
- return /* @__PURE__ */ jsxs8(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20284
+ return /* @__PURE__ */ jsxs8(Box_default, { testID: "tasks-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20284
20285
  /* @__PURE__ */ jsx10(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx10(Text, { bold: true, children: "Task Detail" }) }),
20285
20286
  /* @__PURE__ */ jsx10(Text, { color: "#6B4C9A", children: "Press Escape to go back" }),
20286
20287
  /* @__PURE__ */ jsx10(Text, { children: " " }),
@@ -20329,8 +20330,8 @@ function TasksView({ onBack }) {
20329
20330
  if (assigneeFilter !== "all") filterParts.push(`assignee:${assigneeFilter}`);
20330
20331
  if (projectFilter !== "all") filterParts.push(`project:${projectFilter}`);
20331
20332
  const filterLabel = filterParts.length > 0 ? filterParts.join(" ") : "none";
20332
- return /* @__PURE__ */ jsxs8(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20333
- /* @__PURE__ */ jsx10(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx10(Text, { bold: true, children: "Task Board" }) }),
20333
+ return /* @__PURE__ */ jsxs8(Box_default, { testID: "tasks-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
20334
+ /* @__PURE__ */ jsx10(Box_default, { testID: "tasks-list", borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx10(Text, { bold: true, children: "Task Board" }) }),
20334
20335
  /* @__PURE__ */ jsx10(Text, { children: " " }),
20335
20336
  /* @__PURE__ */ jsxs8(Text, { color: "#6B4C9A", children: [
20336
20337
  filteredTasks.length,
@@ -21068,7 +21069,7 @@ function GatewayView({ onBack }) {
21068
21069
  /* @__PURE__ */ jsx11(Text, { color: "#6B4C9A", children: "External agents and communication channels will appear here once set up." })
21069
21070
  ] });
21070
21071
  }
21071
- return /* @__PURE__ */ jsxs9(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21072
+ return /* @__PURE__ */ jsxs9(Box_default, { testID: "gateway-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21072
21073
  /* @__PURE__ */ jsx11(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx11(Text, { bold: true, children: "Gateway Monitor" }) }),
21073
21074
  /* @__PURE__ */ jsxs9(Text, { color: "#6B4C9A", children: [
21074
21075
  "\u2191\u2193",
@@ -21492,7 +21493,7 @@ function TeamView({ onBack, onViewSessions }) {
21492
21493
  const totalCount = members.length + externals.length;
21493
21494
  const selected = allItems[selectedIdx];
21494
21495
  if (showDetail && selected) {
21495
- return /* @__PURE__ */ jsxs10(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21496
+ return /* @__PURE__ */ jsxs10(Box_default, { testID: "team-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21496
21497
  /* @__PURE__ */ jsx12(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx12(Text, { bold: true, children: "Employee Detail" }) }),
21497
21498
  /* @__PURE__ */ jsx12(Text, { color: "#6B4C9A", children: "Press Escape to go back" }),
21498
21499
  /* @__PURE__ */ jsx12(Text, { children: " " }),
@@ -21529,8 +21530,8 @@ function TeamView({ onBack, onViewSessions }) {
21529
21530
  ] })
21530
21531
  ] });
21531
21532
  }
21532
- return /* @__PURE__ */ jsxs10(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21533
- /* @__PURE__ */ jsx12(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx12(Text, { bold: true, children: "Team Roster" }) }),
21533
+ return /* @__PURE__ */ jsxs10(Box_default, { testID: "team-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
21534
+ /* @__PURE__ */ jsx12(Box_default, { testID: "team-roster", borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx12(Text, { bold: true, children: "Team Roster" }) }),
21534
21535
  /* @__PURE__ */ jsxs10(Text, { color: "#6B4C9A", children: [
21535
21536
  totalCount,
21536
21537
  " agents | \u2191\u2193 navigate | Enter details | a add | s sessions"
@@ -22095,7 +22096,7 @@ function WikiView({ onBack }) {
22095
22096
  ] }) : null
22096
22097
  ] });
22097
22098
  }
22098
- return /* @__PURE__ */ jsxs11(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
22099
+ return /* @__PURE__ */ jsxs11(Box_default, { testID: "wiki-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
22099
22100
  /* @__PURE__ */ jsx13(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx13(Text, { bold: true, children: "Wiki" }) }),
22100
22101
  /* @__PURE__ */ jsxs11(Box_default, { gap: 2, children: [
22101
22102
  /* @__PURE__ */ jsxs11(Text, { color: "#6B4C9A", children: [
@@ -22386,7 +22387,7 @@ function SettingsView({ onBack }) {
22386
22387
  const sectionMarker = (idx) => selectedSection === idx ? "\u25B8 " : " ";
22387
22388
  const anyGateway = gateway.adapters.some((a) => a.configured);
22388
22389
  const formatLimit = (n) => n === -1 ? "unlimited" : n.toLocaleString();
22389
- return /* @__PURE__ */ jsxs12(Box_default, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
22390
+ return /* @__PURE__ */ jsxs12(Box_default, { testID: "settings-view", flexDirection: "column", flexGrow: 1, paddingX: 1, children: [
22390
22391
  /* @__PURE__ */ jsx14(Box_default, { borderStyle: "single", borderColor: "#3D3660", paddingX: 1, alignSelf: "flex-start", children: /* @__PURE__ */ jsx14(Text, { bold: true, children: "Settings" }) }),
22391
22392
  /* @__PURE__ */ jsx14(Text, { color: DIM, children: "\u2191\u2193 navigate sections r refresh" }),
22392
22393
  /* @__PURE__ */ jsx14(Text, { children: " " }),
@@ -22568,7 +22569,7 @@ function DebugPanel() {
22568
22569
  orgBus.offAny(handler);
22569
22570
  };
22570
22571
  }, []);
22571
- return /* @__PURE__ */ jsxs13(Box_default, { flexDirection: "column", borderStyle: "single", borderColor: "#6B4C9A", flexGrow: 1, paddingX: 1, children: [
22572
+ return /* @__PURE__ */ jsxs13(Box_default, { testID: "debug-panel", flexDirection: "column", borderStyle: "single", borderColor: "#6B4C9A", flexGrow: 1, paddingX: 1, children: [
22572
22573
  /* @__PURE__ */ jsx15(Text, { bold: true, color: "#F5D76E", children: "Debug \u2014 Live Events" }),
22573
22574
  /* @__PURE__ */ jsx15(Text, { color: "#3D3660", children: "\u2500".repeat(40) }),
22574
22575
  events.length === 0 ? /* @__PURE__ */ jsx15(Text, { color: "#3D3660", children: "Waiting for events..." }) : events.slice(-DISPLAY_EVENTS).map(({ event, id }) => {
@@ -22613,6 +22614,7 @@ function HelpOverlay({ tabName, shortcuts }) {
22613
22614
  return /* @__PURE__ */ jsxs14(
22614
22615
  Box_default,
22615
22616
  {
22617
+ testID: "help-overlay",
22616
22618
  flexDirection: "column",
22617
22619
  borderStyle: "double",
22618
22620
  borderColor: "#6B4C9A",
@@ -22757,8 +22759,8 @@ function App2() {
22757
22759
  wiki: /* @__PURE__ */ jsx17(WikiView, { onBack: () => setFocus("sidebar") }),
22758
22760
  settings: /* @__PURE__ */ jsx17(SettingsView, { onBack: () => setFocus("sidebar") })
22759
22761
  };
22760
- return /* @__PURE__ */ jsx17(ErrorBoundary2, { children: /* @__PURE__ */ jsx17(AlternateScreen, { children: /* @__PURE__ */ jsx17(DemoProvider, { demo: isDemo, children: /* @__PURE__ */ jsxs15(Box_default, { flexDirection: "column", flexGrow: 1, children: [
22761
- /* @__PURE__ */ jsxs15(Box_default, { flexGrow: 1, children: [
22762
+ return /* @__PURE__ */ jsx17(ErrorBoundary2, { children: /* @__PURE__ */ jsx17(AlternateScreen, { children: /* @__PURE__ */ jsx17(DemoProvider, { demo: isDemo, children: /* @__PURE__ */ jsxs15(Box_default, { testID: "app-root", flexDirection: "column", flexGrow: 1, children: [
22763
+ /* @__PURE__ */ jsxs15(Box_default, { testID: "app-content", flexGrow: 1, children: [
22762
22764
  /* @__PURE__ */ jsx17(Sidebar, { active: section, onSelect: setSection, onQuit: exit, focused: focus === "sidebar" }),
22763
22765
  showHelp ? /* @__PURE__ */ jsx17(
22764
22766
  HelpOverlay,
@@ -672,24 +672,70 @@ function summarizeSymlinkResults(results) {
672
672
  }
673
673
 
674
674
  // src/bin/install.ts
675
- import { existsSync as existsSync5, readFileSync as readFileSync4, unlinkSync } from "fs";
675
+ import { existsSync as existsSync5, readFileSync as readFileSync4, unlinkSync, openSync, closeSync } from "fs";
676
+ import { spawn } from "child_process";
676
677
  import path5 from "path";
677
678
  import { homedir } from "os";
678
- function killStaleDaemon() {
679
+ var EXE_DIR = path5.join(homedir(), ".exe-os");
680
+ function restartDaemon() {
681
+ const pidPath = path5.join(EXE_DIR, "exed.pid");
682
+ const sockPath = path5.join(EXE_DIR, "exed.sock");
679
683
  try {
680
- const pidPath = path5.join(homedir(), ".exe-os", "exed.pid");
681
- if (!existsSync5(pidPath)) return;
682
- const pid = parseInt(readFileSync4(pidPath, "utf8").trim(), 10);
683
- if (isNaN(pid)) return;
684
- process.kill(pid, "SIGTERM");
684
+ if (existsSync5(pidPath)) {
685
+ const pid = parseInt(readFileSync4(pidPath, "utf8").trim(), 10);
686
+ if (!isNaN(pid) && pid > 0) {
687
+ try {
688
+ process.kill(pid, "SIGTERM");
689
+ } catch {
690
+ }
691
+ }
692
+ try {
693
+ unlinkSync(pidPath);
694
+ } catch {
695
+ }
696
+ }
685
697
  try {
686
- unlinkSync(pidPath);
698
+ unlinkSync(sockPath);
687
699
  } catch {
688
700
  }
689
- process.stderr.write(`exe-os: restarted daemon (PID ${pid}) for new version
690
- `);
691
701
  } catch {
692
702
  }
703
+ try {
704
+ const pkgRoot = resolvePackageRoot();
705
+ const daemonPath = path5.join(pkgRoot, "dist", "lib", "exe-daemon.js");
706
+ if (!existsSync5(daemonPath)) {
707
+ process.stderr.write(`exe-os: daemon not found at ${daemonPath} \u2014 skipping respawn
708
+ `);
709
+ return;
710
+ }
711
+ const logPath = path5.join(EXE_DIR, "exed.log");
712
+ let stderrFd = "ignore";
713
+ try {
714
+ stderrFd = openSync(logPath, "a");
715
+ } catch {
716
+ }
717
+ const child = spawn(process.execPath, [daemonPath], {
718
+ detached: true,
719
+ stdio: ["ignore", "ignore", stderrFd],
720
+ env: {
721
+ ...process.env,
722
+ EXE_DAEMON_SOCK: sockPath,
723
+ EXE_DAEMON_PID: pidPath
724
+ }
725
+ });
726
+ child.unref();
727
+ if (typeof stderrFd === "number") {
728
+ try {
729
+ closeSync(stderrFd);
730
+ } catch {
731
+ }
732
+ }
733
+ process.stderr.write(`exe-os: daemon restarted (new PID spawned)
734
+ `);
735
+ } catch (err) {
736
+ process.stderr.write(`exe-os: daemon respawn failed: ${err instanceof Error ? err.message : String(err)}
737
+ `);
738
+ }
693
739
  }
694
740
  var args = process.argv.slice(2);
695
741
  if (args.includes("--commands-only")) {
@@ -707,7 +753,7 @@ if (args.includes("--commands-only")) {
707
753
  } else if (args.includes("--global")) {
708
754
  try {
709
755
  await runInstaller();
710
- killStaleDaemon();
756
+ restartDaemon();
711
757
  } catch (err) {
712
758
  console.error(
713
759
  "Installation failed:",